File size: 5,722 Bytes
1f7ead8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import React, { useState } from 'react';
import {
    Headphones, Video, Network, FileText, Component,
    HelpCircle, Package, Columns, Projector, Activity,
    Loader2, X, BookOpen
} from 'lucide-react';
import { generateSourceContent } from '../api';

// Tool definitions
const TOOLS = [
    { id: 'audio', label: 'Audio Overview', icon: Headphones, color: 'text-purple-600', bg: 'bg-purple-50' },
    { id: 'video', label: 'Video Overview', icon: Video, color: 'text-red-600', bg: 'bg-red-50' },
    { id: 'mind_map', label: 'Mind Map', icon: Network, color: 'text-blue-600', bg: 'bg-blue-50' },
    { id: 'reports', label: 'Reports', icon: FileText, color: 'text-emerald-600', bg: 'bg-emerald-50' },
    { id: 'flashcards', label: 'Flashcards', icon: Component, color: 'text-amber-600', bg: 'bg-amber-50' },
    { id: 'quiz', label: 'Quiz', icon: HelpCircle, color: 'text-cyan-600', bg: 'bg-cyan-50' },
    { id: 'artifact', label: 'Create Artifact', icon: Package, color: 'text-indigo-600', bg: 'bg-indigo-50' },
    { id: 'infographic', label: 'Infographic', icon: Columns, color: 'text-pink-600', bg: 'bg-pink-50' },
    { id: 'slides', label: 'Slide Deck', icon: Projector, color: 'text-orange-600', bg: 'bg-orange-50' },
    { id: 'data_table', label: 'Data Table', icon: Activity, color: 'text-teal-600', bg: 'bg-teal-50' },
];

const SourceGuide = ({ onGenerate, activeCitation, onCloseCitation, notebookId }) => {
    const [generating, setGenerating] = useState(null);

    const handleToolClick = async (toolId) => {
        if (generating) return;
        setGenerating(toolId);
        try {
            const result = await generateSourceContent(toolId, notebookId);
            // Callback to Notebook to insert the result
            onGenerate(toolId, result.answer);
        } catch (error) {
            console.error(error);
            alert("Failed to generate content: " + (error.response?.data?.detail || error.message));
        } finally {
            setGenerating(null);
        }
    };

    // If a citation is active, show the Citation View (mini-panel)
    if (activeCitation) {
        return (
            <div className="h-full border-l border-slate-200 bg-white flex flex-col">

                <div className="p-4 border-b border-slate-100 flex items-center justify-between">

                    <h3 className="font-semibold text-slate-700 flex items-center gap-2">

                        <BookOpen size={16} /> Source Guide

                    </h3>

                    <button onClick={onCloseCitation} className="p-1 hover:bg-slate-100 rounded-full text-slate-400">

                        <X size={16} />

                    </button>

                </div>

                <div className="p-4 flex-1 overflow-y-auto">

                    <div className="bg-blue-50 border border-blue-100 p-4 rounded-xl mb-4">

                        <span className="text-xs font-bold text-blue-600 uppercase">Selected Source</span>

                        <h4 className="font-medium text-slate-900 mt-1">{activeCitation.paper_id}</h4>

                    </div>

                    <p className="p-4 bg-slate-50 rounded-lg text-slate-700 italic border-l-4 border-slate-300">

                        "{activeCitation.text_snippet}"

                    </p>

                    <div className="mt-4 text-center">

                        <button onClick={onCloseCitation} className="text-sm text-blue-600 hover:underline">

                            Back to Tools

                        </button>

                    </div>

                </div>

            </div>
        );
    }

    return (
        <div className="h-full border-l border-slate-200 bg-white flex flex-col">

            <div className="p-6 border-b border-slate-100">

                <h2 className="text-lg font-bold text-slate-800">Source Guide</h2>

                <p className="text-sm text-slate-500 mt-1">Transform your sources into...</p>

            </div>



            <div className="flex-1 overflow-y-auto p-4">

                <div className="grid grid-cols-2 gap-3">

                    {TOOLS.map((tool) => {

                        const Icon = tool.icon;

                        const isProcessing = generating === tool.id;

                        return (

                            <button

                                key={tool.id}

                                onClick={() => handleToolClick(tool.id)}

                                disabled={!!generating}

                                className={`flex flex-col items-center justify-center gap-3 p-4 rounded-xl border border-slate-100 hover:border-slate-300 hover:shadow-md transition-all text-center bg-white group disabled:opacity-50 h-32 ${isProcessing ? 'bg-slate-50' : ''}`}

                            >

                                <div className={`w-12 h-12 rounded-full flex items-center justify-center ${tool.bg} ${tool.color} group-hover:scale-110 transition-transform`}>

                                    {isProcessing ? <Loader2 size={24} className="animate-spin" /> : <Icon size={24} />}

                                </div>

                                <div>

                                    <h3 className="font-semibold text-slate-700 text-sm">{tool.label}</h3>

                                    {isProcessing && <p className="text-[10px] text-slate-400 mt-0.5">Generating...</p>}

                                </div>

                            </button>

                        );

                    })}

                </div>

            </div>

        </div>
    );
};

export default SourceGuide;