From 56590e93297a1e25304a7fd1b255d26386bb3b71 Mon Sep 17 00:00:00 2001 From: MaheshtheDev <38828053+MaheshtheDev@users.noreply.github.com> Date: Fri, 3 Oct 2025 07:51:00 +0000 Subject: [PATCH] feat: delete memories and theme issues across the app (#449) # Add document deletion functionality and fix UI theme issues This PR adds the ability to delete documents and their associated memories across all content card types (Google Docs, Notes, Tweets, and Websites). Each card now includes: - A delete button that appears on hover - A confirmation dialog to prevent accidental deletions - Proper event handling to avoid triggering card clicks when using delete controls Additionally, this PR fixes various UI theme issues: - Updates button styling in the ActionButtons component - Improves theme consistency by replacing hardcoded colors with theme variables - Fixes text color issues in login page components - Ensures proper color contrast in various UI elements The masonry layout was also improved to properly re-render when documents are removed. --- .../components/content-cards/google-docs.tsx | 88 ++++++++++--- apps/web/components/content-cards/note.tsx | 96 +++++++++++--- apps/web/components/content-cards/tweet.tsx | 66 +++++++++- apps/web/components/content-cards/website.tsx | 88 +++++++++++-- apps/web/components/masonry-memory-list.tsx | 8 +- .../views/add-memory/action-buttons.tsx | 118 +++++++++--------- .../web/components/views/add-memory/index.tsx | 7 +- packages/ui/button/external-auth.tsx | 4 +- packages/ui/components/text-separator.tsx | 6 +- packages/ui/input/labeled-input.tsx | 4 +- packages/ui/pages/login.tsx | 22 ++-- packages/ui/text/label/label-2-medium.tsx | 2 +- packages/ui/text/label/label-2-regular.tsx | 2 +- packages/ui/text/label/label-3-medium.tsx | 2 +- packages/ui/text/label/label-3-regular.tsx | 2 +- 15 files changed, 383 insertions(+), 132 deletions(-) diff --git a/apps/web/components/content-cards/google-docs.tsx b/apps/web/components/content-cards/google-docs.tsx index 22f06f77..0306876d 100644 --- a/apps/web/components/content-cards/google-docs.tsx +++ b/apps/web/components/content-cards/google-docs.tsx @@ -2,8 +2,18 @@ import { Card, CardContent } from "@repo/ui/components/card" import { Badge } from "@repo/ui/components/badge" -import { ExternalLink, FileText, Brain } from "lucide-react" -import { useState } from "react" +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "@repo/ui/components/alert-dialog" +import { ExternalLink, FileText, Brain, Trash2 } from "lucide-react" import { cn } from "@lib/utils" import { colors } from "@repo/ui/memory-graph/constants" import { getPastelBackgroundColor } from "../memories-utils" @@ -14,6 +24,7 @@ interface GoogleDocsCardProps { description?: string | null className?: string onClick?: () => void + onDelete?: () => void showExternalLink?: boolean activeMemories?: Array<{ id: string; isForgotten?: boolean }> lastModified?: string | Date @@ -25,12 +36,11 @@ export const GoogleDocsCard = ({ description, className, onClick, + onDelete, showExternalLink = true, activeMemories, lastModified, }: GoogleDocsCardProps) => { - const [imageError, setImageError] = useState(false) - const handleCardClick = () => { if (onClick) { onClick() @@ -57,6 +67,54 @@ export const GoogleDocsCard = ({ backgroundColor: getPastelBackgroundColor(url || title || "googledocs"), }} > + {onDelete && ( + + + + + + + Delete Document + + Are you sure you want to delete this document and all its + related memories? This action cannot be undone. + + + + { + e.stopPropagation() + }} + > + Cancel + + { + e.stopPropagation() + onDelete() + }} + > + Delete + + + + + )} +
@@ -99,16 +157,18 @@ export const GoogleDocsCard = ({
- {showExternalLink && ( - - )} +
+ {showExternalLink && ( + + )} +
diff --git a/apps/web/components/content-cards/note.tsx b/apps/web/components/content-cards/note.tsx index e7703d9b..b0014bf6 100644 --- a/apps/web/components/content-cards/note.tsx +++ b/apps/web/components/content-cards/note.tsx @@ -1,8 +1,19 @@ import { Badge } from "@repo/ui/components/badge" import { Card, CardContent, CardHeader } from "@repo/ui/components/card" +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "@repo/ui/components/alert-dialog" import { colors } from "@repo/ui/memory-graph/constants" -import { Brain, ExternalLink } from "lucide-react" +import { Brain, ExternalLink, Trash2 } from "lucide-react" import { cn } from "@lib/utils" import { formatDate, @@ -32,6 +43,7 @@ export const NoteCard = ({ activeMemories, forgottenMemories, onOpenDetails, + onDelete, }: NoteCardProps) => { return ( + + + + + + + Delete Document + + Are you sure you want to delete this document and all its related + memories? This action cannot be undone. + + + + { + e.stopPropagation() + }} + > + Cancel + + { + e.stopPropagation() + onDelete(document) + }} + > + Delete + + + + +
@@ -59,23 +117,25 @@ export const NoteCard = ({ {document.title || "Untitled Document"}

- {document.url && ( - - )} +
+ {document.url && ( + + )} +
{formatDate(document.createdAt)}
diff --git a/apps/web/components/content-cards/tweet.tsx b/apps/web/components/content-cards/tweet.tsx index 3f46d6cc..34db9eb5 100644 --- a/apps/web/components/content-cards/tweet.tsx +++ b/apps/web/components/content-cards/tweet.tsx @@ -14,7 +14,18 @@ import { enrichTweet, } from "react-tweet" import { Badge } from "@repo/ui/components/badge" -import { Brain } from "lucide-react" +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "@repo/ui/components/alert-dialog" +import { Brain, Trash2 } from "lucide-react" import { colors } from "@repo/ui/memory-graph/constants" import { getPastelBackgroundColor } from "../memories-utils" @@ -71,18 +82,69 @@ const CustomTweet = ({ export const TweetCard = ({ data, activeMemories, + onDelete, }: { data: Tweet activeMemories?: Array<{ id: string; isForgotten?: boolean }> + onDelete?: () => void }) => { return (
+ + {onDelete && ( + + + + + + + Delete Document + + Are you sure you want to delete this document and all its + related memories? This action cannot be undone. + + + + { + e.stopPropagation() + }} + > + Cancel + + { + e.stopPropagation() + onDelete() + }} + > + Delete + + + + + )} + {activeMemories && activeMemories.length > 0 && (
void + onDelete?: () => void showExternalLink?: boolean } @@ -23,6 +36,7 @@ export const WebsiteCard = ({ description, className, onClick, + onDelete, showExternalLink = true, }: WebsiteCardProps) => { const [imageError, setImageError] = useState(false) @@ -51,7 +65,7 @@ export const WebsiteCard = ({ return ( + {onDelete && ( + + + + + + + Delete Document + + Are you sure you want to delete this document and all its + related memories? This action cannot be undone. + + + + { + e.stopPropagation() + }} + > + Cancel + + { + e.stopPropagation() + onDelete() + }} + > + Delete + + + + + )} + {image && !imageError && (
@@ -75,16 +137,18 @@ export const WebsiteCard = ({
{title} - {showExternalLink && ( - - )} +
+ {showExternalLink && ( + + )} +
{description && ( diff --git a/apps/web/components/masonry-memory-list.tsx b/apps/web/components/masonry-memory-list.tsx index 2f634f74..93326e49 100644 --- a/apps/web/components/masonry-memory-list.tsx +++ b/apps/web/components/masonry-memory-list.tsx @@ -63,6 +63,7 @@ const DocumentCard = memo( description={document.content} activeMemories={activeMemories} lastModified={document.updatedAt || document.createdAt} + onDelete={() => onDelete(document)} /> ) } @@ -77,6 +78,7 @@ const DocumentCard = memo( document.metadata?.sm_internal_twitter_metadata as unknown as Tweet } activeMemories={activeMemories} + onDelete={() => onDelete(document)} /> ) } @@ -87,6 +89,7 @@ const DocumentCard = memo( url={document.url} title={document.title || "Untitled Document"} image={document.ogImage} + onDelete={() => onDelete(document)} /> ) } @@ -212,9 +215,7 @@ export const MasonryMemoryList = ({ ) : isLoading ? (
-
+
Loading memory list... @@ -232,6 +233,7 @@ export const MasonryMemoryList = ({ data-theme="light" > d.id).join(",")}`} items={filteredDocuments} render={renderDocumentCard} columnGutter={16} diff --git a/apps/web/components/views/add-memory/action-buttons.tsx b/apps/web/components/views/add-memory/action-buttons.tsx index fc901ba9..3f93fe17 100644 --- a/apps/web/components/views/add-memory/action-buttons.tsx +++ b/apps/web/components/views/add-memory/action-buttons.tsx @@ -1,67 +1,67 @@ -import { Button } from '@repo/ui/components/button'; -import { Loader2, type LucideIcon } from 'lucide-react'; -import { motion } from 'motion/react'; +import { Button } from "@repo/ui/components/button" +import { Loader2, type LucideIcon } from "lucide-react" +import { motion } from "motion/react" interface ActionButtonsProps { - onCancel: () => void; - onSubmit?: () => void; - submitText: string; - submitIcon?: LucideIcon; - isSubmitting?: boolean; - isSubmitDisabled?: boolean; - submitType?: 'button' | 'submit'; - className?: string; + onCancel: () => void + onSubmit?: () => void + submitText: string + submitIcon?: LucideIcon + isSubmitting?: boolean + isSubmitDisabled?: boolean + submitType?: "button" | "submit" + className?: string } export function ActionButtons({ - onCancel, - onSubmit, - submitText, - submitIcon: SubmitIcon, - isSubmitting = false, - isSubmitDisabled = false, - submitType = 'submit', - className = '', + onCancel, + onSubmit, + submitText, + submitIcon: SubmitIcon, + isSubmitting = false, + isSubmitDisabled = false, + submitType = "submit", + className = "", }: ActionButtonsProps) { - return ( -
- + return ( +
+ - - - -
- ); + + + +
+ ) } diff --git a/apps/web/components/views/add-memory/index.tsx b/apps/web/components/views/add-memory/index.tsx index a78e7629..d9c6aef8 100644 --- a/apps/web/components/views/add-memory/index.tsx +++ b/apps/web/components/views/add-memory/index.tsx @@ -88,7 +88,10 @@ export function AddMemoryView({ const [newProjectName, setNewProjectName] = useState("") // Check memory limits - const { data: memoriesCheck } = fetchMemoriesFeature(autumn, !autumn.isLoading) + const { data: memoriesCheck } = fetchMemoriesFeature( + autumn, + !autumn.isLoading, + ) const memoriesUsed = memoriesCheck?.usage ?? 0 const memoriesLimit = memoriesCheck?.included_usage ?? 0 @@ -757,7 +760,7 @@ export function AddMemoryView({ {({ state, handleChange, handleBlur }) => ( <> {authIcon} - + Continue with {authProvider} diff --git a/packages/ui/components/text-separator.tsx b/packages/ui/components/text-separator.tsx index 87ffb772..6e3e671b 100644 --- a/packages/ui/components/text-separator.tsx +++ b/packages/ui/components/text-separator.tsx @@ -14,11 +14,11 @@ export function TextSeparator({ className={cn("flex gap-4 items-center justify-center", className)} {...props} > -
- +
+ {text} -
+
); } diff --git a/packages/ui/input/labeled-input.tsx b/packages/ui/input/labeled-input.tsx index 8b465f4b..84f205fe 100644 --- a/packages/ui/input/labeled-input.tsx +++ b/packages/ui/input/labeled-input.tsx @@ -21,11 +21,11 @@ export function LabeledInput({ }: LabeledInputProps) { return (
- {label} + {label}
- Almost there! - + Almost there! + Click the magic link we've sent to{" "} - {submittedEmail}. + {submittedEmail}.
@@ -221,11 +221,11 @@ export function LoginPage({ ) : (