- Add 'Twilight Velvet' color palette to globals.css with OKLCH values - Update SettingsPage headers, cards, and dialogs to use semantic theme variables - Update HistoryCard, HistoryFeed, and DraftContent to support dark mode - Update ProviderSelector and ProviderList to use custom card background (#2A2A3D) - Add ThemeToggle component with improved visibility - Ensure consistent use of 'bg-card', 'text-foreground', and 'text-muted-foreground'
108 lines
4.5 KiB
TypeScript
108 lines
4.5 KiB
TypeScript
'use client';
|
|
|
|
import { useChatStore } from '@/store/use-chat';
|
|
import { Button } from '@/components/ui/button';
|
|
import {
|
|
Sheet,
|
|
SheetContent,
|
|
SheetHeader,
|
|
SheetTitle,
|
|
SheetDescription,
|
|
SheetFooter,
|
|
} from '@/components/ui/sheet';
|
|
import { ThumbsUp, ThumbsDown, RefreshCw } from 'lucide-react';
|
|
import ReactMarkdown from 'react-markdown';
|
|
|
|
export function DraftSheet() {
|
|
const { phase, currentDraft, setPhase, resetSession } = useChatStore();
|
|
const isOpen = phase === 'review' && !!currentDraft;
|
|
|
|
const handleKeep = async () => {
|
|
if (!currentDraft) return;
|
|
|
|
try {
|
|
// Import dynamically to avoid side-effects during render if possible,
|
|
// or just import at top. We'll stick to dynamic since DraftService might not be SSR friendly
|
|
// without checks, but it handles it internally.
|
|
const { DraftService } = await import('@/lib/db/draft-service');
|
|
const { useSessionStore } = await import('@/store/use-session');
|
|
const sessionId = useSessionStore.getState().activeSessionId;
|
|
|
|
if (!sessionId) {
|
|
console.error("No active session ID");
|
|
return;
|
|
}
|
|
|
|
await DraftService.saveDraft({
|
|
sessionId,
|
|
title: currentDraft.title,
|
|
content: currentDraft.lesson, // Using lesson as content for now, or construct full markdown?
|
|
// Let's construct a nice markdown
|
|
// Actually the draft artifact has title, insight, lesson.
|
|
// We should probably save the raw JSON or a formatted textual representation.
|
|
// Let's save formatted text.
|
|
createdAt: Date.now(),
|
|
updatedAt: Date.now(),
|
|
status: 'completed',
|
|
completedAt: Date.now(),
|
|
tags: []
|
|
});
|
|
|
|
// Redirect to history or show success
|
|
window.location.href = '/history';
|
|
|
|
resetSession();
|
|
} catch (error) {
|
|
console.error("Failed to save draft:", error);
|
|
}
|
|
};
|
|
|
|
const handleRefine = () => {
|
|
// Logic for refinement (Story 3.5)
|
|
// For now, close sheet and persist state
|
|
setPhase('drafting'); // Go back or stay?
|
|
// Actually, refinement usually means going back to chat Elicitation or having a specialized Refinement Mode.
|
|
// Let's just close for now.
|
|
setPhase('elicitation');
|
|
};
|
|
|
|
if (!currentDraft) return null;
|
|
|
|
return (
|
|
<Sheet open={isOpen} onOpenChange={(open) => !open && handleRefine()}>
|
|
<SheetContent side="bottom" className="h-[80vh] sm:h-[600px] rounded-t-[20px] pt-10">
|
|
<SheetHeader className="text-left mb-6">
|
|
<SheetTitle className="font-serif text-3xl font-bold bg-gradient-to-r from-indigo-500 to-purple-600 bg-clip-text text-transparent">
|
|
{currentDraft.title}
|
|
</SheetTitle>
|
|
<SheetDescription className="text-lg text-slate-600 italic">
|
|
" {currentDraft.insight} "
|
|
</SheetDescription>
|
|
</SheetHeader>
|
|
|
|
<div className="space-y-6 overflow-y-auto pb-20">
|
|
<div className="prose dark:prose-invert max-w-none">
|
|
<h3 className="font-serif text-xl border-l-4 border-indigo-500 pl-4 py-1">
|
|
The Lesson
|
|
</h3>
|
|
<p className="text-lg leading-relaxed text-slate-700 dark:text-slate-300">
|
|
{currentDraft.lesson}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<SheetFooter className="absolute bottom-0 left-0 right-0 p-6 bg-white/80 dark:bg-zinc-950/80 backdrop-blur-md border-t border-slate-200 flex flex-row gap-4 justify-between sm:justify-end">
|
|
<Button variant="outline" size="lg" className="flex-1 sm:flex-none gap-2" onClick={handleRefine}>
|
|
<ThumbsDown className="w-5 h-5" />
|
|
Refine
|
|
</Button>
|
|
<Button size="lg" className="flex-1 sm:flex-none gap-2 bg-indigo-600 hover:bg-indigo-700 text-white" onClick={handleKeep}>
|
|
<ThumbsUp className="w-5 h-5" />
|
|
Keep It
|
|
</Button>
|
|
</SheetFooter>
|
|
</SheetContent>
|
|
</Sheet>
|
|
);
|
|
}
|