feat: improve AI Chat UX, add notebook summary, and fix shared/reminders routing
Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 1m50s

This commit is contained in:
Antigravity
2026-05-09 14:40:36 +00:00
parent 66e957fd59
commit 368b43cb8e
20 changed files with 292 additions and 196 deletions

View File

@@ -152,18 +152,18 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
return (
<Button
onClick={() => setIsOpen(true)}
className="fixed bottom-6 right-6 h-12 w-12 rounded-full shadow-xl z-40 transition-transform hover:scale-105 bg-[#E9ECEF] text-[#1C1C1C] hover:bg-[#E9ECEF]/80 border border-black/5"
className="fixed bottom-6 right-6 h-12 w-12 rounded-full shadow-xl z-40 transition-transform hover:scale-105 bg-muted text-foreground hover:bg-muted/80 border border-border"
size="icon"
title={t('ai.openAssistant')}
>
<Sparkles className="h-5 w-5" />
<Sparkles className="h-5 w-5 text-memento-accent" />
</Button>
)
}
return (
<aside className={cn(
"fixed bottom-20 right-6 border border-border/40 bg-[#FDFDFE] flex flex-col z-40 shadow-2xl rounded-2xl overflow-hidden transition-all duration-300",
"fixed bottom-20 right-6 border border-border/40 bg-background flex flex-col z-40 shadow-2xl rounded-2xl overflow-hidden transition-all duration-300",
isExpanded ? "w-[80vw] h-[85vh] max-w-[1200px]" : "h-[700px] max-h-[85vh] w-[360px]"
)}>
{/* Header */}
@@ -207,7 +207,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
onClick={() => setActiveTab('chat')}
className={cn(
"flex-1 pb-3 border-b-2 text-sm font-semibold flex items-center justify-center gap-2 transition-all",
activeTab === 'chat' ? "border-[#75B2D6] text-[#75B2D6]" : "border-transparent text-muted-foreground hover:text-foreground"
activeTab === 'chat' ? "border-memento-blue text-memento-blue" : "border-transparent text-muted-foreground hover:text-foreground"
)}
>
<Bot className="h-4 w-4" /> {t('ai.chatTab')}
@@ -216,7 +216,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
onClick={() => setActiveTab('insights')}
className={cn(
"flex-1 pb-3 border-b-2 text-sm font-semibold flex items-center justify-center gap-2 transition-all",
activeTab === 'insights' ? "border-[#75B2D6] text-[#75B2D6]" : "border-transparent text-muted-foreground hover:text-foreground"
activeTab === 'insights' ? "border-memento-blue text-memento-blue" : "border-transparent text-muted-foreground hover:text-foreground"
)}
>
<Sparkles className="h-4 w-4" /> {t('ai.insightsTab')}
@@ -225,7 +225,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
onClick={() => setActiveTab('history')}
className={cn(
"flex-1 pb-3 border-b-2 text-sm font-semibold flex items-center justify-center gap-2 transition-all",
activeTab === 'history' ? "border-[#75B2D6] text-[#75B2D6]" : "border-transparent text-muted-foreground hover:text-foreground"
activeTab === 'history' ? "border-memento-blue text-memento-blue" : "border-transparent text-muted-foreground hover:text-foreground"
)}
>
<History className="h-4 w-4" /> {t('ai.historyTab')}
@@ -239,10 +239,10 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
{/* AI Welcome Message */}
{messages.length === 0 && (
<div className="flex gap-3">
<div className="w-8 h-8 rounded-full bg-[#75B2D6]/10 text-[#75B2D6] flex items-center justify-center flex-shrink-0 border border-[#75B2D6]/20">
<div className="w-8 h-8 rounded-full bg-memento-blue/10 text-memento-blue flex items-center justify-center flex-shrink-0 border border-memento-blue/20">
<Bot className="h-4 w-4" />
</div>
<div className="bg-[#FDFDFE] border border-border/50 p-3.5 rounded-2xl rounded-tl-sm shadow-sm">
<div className="bg-background border border-border/50 p-3.5 rounded-2xl rounded-tl-sm shadow-sm">
<p className="text-sm text-foreground leading-relaxed">
{t('ai.welcomeMsg')}
</p>
@@ -260,16 +260,16 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
<div className={cn(
'w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 border text-[10px] font-bold',
msg.role === 'user'
? 'bg-zinc-100 border-zinc-200 text-zinc-600'
: 'bg-[#75B2D6]/10 text-[#75B2D6] border-[#75B2D6]/20',
? 'bg-muted border-border text-muted-foreground'
: 'bg-memento-blue/10 text-memento-blue border-memento-blue/20',
)}>
{msg.role === 'user' ? 'U' : <Bot className="h-4 w-4" />}
</div>
<div className={cn(
'max-w-[85%] p-3.5 rounded-2xl text-sm leading-relaxed shadow-sm',
msg.role === 'user'
? 'bg-[#75B2D6] text-white rounded-tr-sm'
: 'bg-[#FDFDFE] border border-border/50 rounded-tl-sm text-foreground',
? 'bg-memento-blue text-white rounded-tr-sm'
: 'bg-background border border-border/50 rounded-tl-sm text-foreground',
)}>
{msg.role === 'assistant'
? <MarkdownContent content={text} />
@@ -281,10 +281,10 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
{isLoading && (
<div className="flex gap-3">
<div className="w-8 h-8 rounded-full bg-[#75B2D6]/10 text-[#75B2D6] flex items-center justify-center flex-shrink-0 border border-[#75B2D6]/20">
<div className="w-8 h-8 rounded-full bg-memento-blue/10 text-memento-blue flex items-center justify-center flex-shrink-0 border border-memento-blue/20">
<Bot className="h-4 w-4" />
</div>
<div className="bg-[#FDFDFE] border border-border/50 p-3.5 rounded-2xl rounded-tl-sm shadow-sm">
<div className="bg-background border border-border/50 p-3.5 rounded-2xl rounded-tl-sm shadow-sm">
<Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
</div>
</div>
@@ -295,7 +295,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
{activeTab === 'insights' && (
<div className="h-full">
<h3 className="text-sm font-semibold mb-4 flex items-center gap-2"><Sparkles className="h-4 w-4 text-[#75B2D6]" /> {t('ai.summaryLast5')}</h3>
<h3 className="text-sm font-semibold mb-4 flex items-center gap-2"><Sparkles className="h-4 w-4 text-memento-accent" /> {t('ai.summaryLast5')}</h3>
{insightsLoading ? (
<div className="flex flex-col items-center justify-center py-10 opacity-60">
<Loader2 className="h-8 w-8 animate-spin mb-4 text-muted-foreground" />
@@ -323,7 +323,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
history.map(conv => (
<button
key={conv.id}
className="w-full text-left p-3 rounded-xl border border-border/50 hover:bg-muted/50 hover:border-[#75B2D6]/30 transition-all flex flex-col gap-1"
className="w-full text-left p-3 rounded-xl border border-border/50 hover:bg-muted/50 hover:border-memento-blue/30 transition-all flex flex-col gap-1"
onClick={() => {
setConversationId(conv.id)
setMessages(conv.messages.map((m: any) => ({
@@ -350,12 +350,12 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
</div>
{/* Input Area & Tone Controls (Only in Chat tab) */}
<div className={cn("p-4 border-t border-border/40 bg-[#FDFDFE] shrink-0", activeTab !== 'chat' && "hidden")}>
<div className={cn("p-4 border-t border-border/40 bg-background shrink-0", activeTab !== 'chat' && "hidden")}>
{/* Context Scope */}
<div className="mb-3">
<span className="text-[9px] font-bold uppercase tracking-widest text-muted-foreground block mb-1.5 ml-1">{t('ai.discussionContextLabel')}</span>
<Select value={chatScope} onValueChange={setChatScope}>
<SelectTrigger className="h-8 text-xs bg-[#FDFDFE] border-border/60">
<SelectTrigger className="h-8 text-xs bg-background border-border/60">
<SelectValue placeholder={t('ai.selectNotebook')} />
</SelectTrigger>
<SelectContent>
@@ -392,8 +392,8 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
className={cn(
"py-1 rounded-md border text-[10px] font-medium transition-all flex flex-col items-center justify-center gap-0.5",
isSelected
? "border-[#75B2D6] bg-[#75B2D6]/10 text-[#75B2D6] shadow-sm"
: "border-border/60 bg-[#FDFDFE] text-muted-foreground hover:bg-muted hover:border-border"
? "border-memento-blue bg-memento-blue/10 text-memento-blue shadow-sm"
: "border-border/60 bg-background text-muted-foreground hover:bg-muted hover:border-border"
)}
>
<Icon className="h-3 w-3" />
@@ -405,7 +405,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
</div>
{/* Text Input */}
<div className="relative bg-[#FDFDFE] border border-border/60 rounded-xl p-1 focus-within:border-[#75B2D6] focus-within:ring-1 focus-within:ring-[#75B2D6]/20 transition-all shadow-sm">
<div className="relative bg-background border border-border/60 rounded-xl p-1 focus-within:border-memento-blue focus-within:ring-1 focus-within:ring-memento-blue/20 transition-all shadow-sm">
<textarea
className="w-full bg-transparent border-none focus:ring-0 resize-none text-sm text-foreground placeholder:text-muted-foreground/70 p-2 min-h-[60px] max-h-[120px]"
placeholder={t('ai.chatPlaceholder')}
@@ -440,7 +440,7 @@ export function AIChat({ showFloatingTrigger = true }: { showFloatingTrigger?: b
) : (
<Button
size="icon"
className="h-8 w-8 rounded-lg bg-[#75B2D6] text-white shadow-sm hover:shadow-md transition-all"
className="h-8 w-8 rounded-lg bg-memento-blue text-white shadow-sm hover:shadow-md transition-all"
onClick={handleSend}
disabled={!input.trim()}
>