roxqtang's picture
Initial commit
8fe50ee
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Badge } from "@/components/ui/badge";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { MessageSquareIcon, UploadIcon, BrainIcon, FolderIcon, BookOpenIcon, ClockIcon, SendIcon } from "lucide-react";
import { useState } from "react";
const GoogleAPI = 'AIzaSyAMqFn0dNAoS75Zo4GUdcD99reEIM2IvzU'
export default function TeachingAssistantDashboard() {
const [message, setMessage] = useState("");
const [chatHistory, setChatHistory] = useState([]);
const handleSend = async () => {
if (message.trim() === "") return;
const newEntry = { sender: "user", content: message };
setChatHistory([...chatHistory, newEntry]);
setMessage("");
try {
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${GoogleAPI}`,
{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
contents: [{ parts: [{ text: message }] }]
})
}
);
const data = await response.json();
console.log("Gemini raw response:", data);
// More robust extraction of AI message
let aiMessage = "";
if (data.candidates && data.candidates.length > 0) {
const candidate = data.candidates[0];
// Try nested parts
if (candidate.content?.parts) {
aiMessage = candidate.content.parts.map(p => p.text).join("\n");
}
// Fallback to simple text
else if (candidate.content?.text) {
aiMessage = candidate.content.text;
}
// Fallback to candidate text
else if (candidate.text) {
aiMessage = candidate.text;
}
}
// Last resort: stringify whole response
if (!aiMessage) {
aiMessage = JSON.stringify(data);
}
setChatHistory(prev => [...prev, { sender: "ai", content: aiMessage }] );
} catch (error) {
console.error("Error connecting to Gemini API:", error);
setChatHistory(prev => [...prev, { sender: "ai", content: "[Error connecting to Gemini API]" }]);
}
};
return (
<div className="grid grid-cols-6 gap-4 p-4 bg-background text-foreground">
{/* Sidebar */}
<div className="col-span-1 bg-muted rounded-2xl p-4 space-y-4 shadow">
<h2 className="text-xl font-semibold">AI Teaching Assistant</h2>
<Button variant="ghost" className="w-full justify-start"><UploadIcon className="mr-2" />Upload</Button>
<Button variant="ghost" className="w-full justify-start"><FolderIcon className="mr-2" />Folders</Button>
<Button variant="ghost" className="w-full justify-start"><BookOpenIcon className="mr-2" />Knowledge Map</Button>
<Button variant="ghost" className="w-full justify-start"><MessageSquareIcon className="mr-2" />Chat Assistant</Button>
<Button variant="ghost" className="w-full justify-start"><ClockIcon className="mr-2" />Review</Button>
</div>
{/* Main Content */}
<div className="col-span-5 space-y-4">
{/* Upload Section */}
<Card>
<CardContent className="p-4">
<h3 className="text-lg font-semibold mb-2">📂 Upload Documents</h3>
<Input type="file" multiple />
<p className="text-sm text-muted-foreground mt-1">Supported: PDF, PPT, TXT</p>
</CardContent>
</Card>
{/* Auto-Summarization */}
<Card>
<CardContent className="p-4">
<h3 className="text-lg font-semibold mb-2">🧠 Auto-Summarization & Tags</h3>
<div className="flex gap-2 flex-wrap">
<Badge variant="secondary">Constructivism</Badge>
<Badge variant="secondary">Cognitive Load</Badge>
<Badge variant="secondary">Assessment Design</Badge>
<Badge variant="secondary">Multimedia Principles</Badge>
</div>
<Textarea className="mt-2" placeholder="Generated summary will appear here..." rows={3} />
</CardContent>
</Card>
{/* Folder View */}
<Card>
<CardContent className="p-4">
<h3 className="text-lg font-semibold mb-2">📁 Knowledge Folders</h3>
<ul className="list-disc list-inside space-y-1">
<li>Instructional Theories (4 docs)</li>
<li>Learner Characteristics (3 docs)</li>
<li>Design Models (5 docs)</li>
<li>Assessment Methods (2 docs)</li>
</ul>
</CardContent>
</Card>
{/* Chat Assistant */}
<Card>
<CardContent className="p-4 space-y-3">
<h3 className="text-lg font-semibold">🤖 Chat with AI Assistant</h3>
<div className="space-y-2 max-h-40 overflow-y-auto bg-muted p-2 rounded">
{chatHistory.map((entry, index) => (
<div key={index} className={`text-sm ${entry.sender === "user" ? "text-right" : "text-left"}`}>
<span className="inline-block px-3 py-1 bg-background rounded shadow">{entry.content}</span>
</div>
))}
</div>
<div className="flex items-center gap-2">
<Input
className="flex-grow"
placeholder="Ask about any concept..."
value={message}
onChange={(e) => setMessage(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleSend()}
/>
<Button onClick={handleSend} variant="default"><SendIcon size={16} /></Button>
</div>
</CardContent>
</Card>
{/* Spaced Repetition */}
<Card>
<CardContent className="p-4">
<h3 className="text-lg font-semibold mb-2">⏳ Review Reminders</h3>
<p className="text-sm">Next review cycle: <strong>Tomorrow (2 docs)</strong> based on Ebbinghaus curve</p>
</CardContent>
</Card>
</div>
</div>
);
}