feat: implement interactive knowledge graph visualization and AI-driven graph optimization dashboard

This commit is contained in:
RaymondVerhoef
2026-05-11 22:32:47 +02:00
parent 8192422263
commit c940c984ad
7 changed files with 207 additions and 34 deletions

View File

@@ -17,7 +17,13 @@ const Dashboard = () => {
const learnDone = storage.get(`user:${currentUser?.id}:week:${weekNumber}:learn_done`, false);
const testResult = getTestResult(currentUser?.id, weekNumber);
const leaderboard = storage.get('leaderboard:current', []).sort((a, b) => b.points - a.points);
const allUsers = storage.get('users:registry', []);
const nonAdminIds = allUsers.filter(u => u.role !== 'admin').map(u => u.id);
const leaderboard = storage.get('leaderboard:current', [])
.filter(u => nonAdminIds.includes(u.userId))
.sort((a, b) => b.points - a.points);
const top3 = leaderboard.slice(0, 3);
const myRank = leaderboard.findIndex(u => u.userId === currentUser?.id) + 1;
const myPoints = leaderboard.find(u => u.userId === currentUser?.id)?.points || 0;

View File

@@ -19,9 +19,12 @@ const Leaderboard = () => {
useEffect(() => {
// Re-evaluate badges before displaying
let data = storage.get('leaderboard:current', []);
// Supplement with users that haven't scored yet
const allUsers = storage.get('users:registry', []);
// Filter out admins from the leaderboard entirely
const nonAdminIds = allUsers.filter(u => u.role !== 'admin').map(u => u.id);
data = data.filter(entry => nonAdminIds.includes(entry.userId));
const userMap = new Map(data.map(u => [u.userId, u]));
allUsers.forEach(user => {

View File

@@ -185,14 +185,14 @@ const Leren = () => {
}
// ── Overview ──────────────────────────────────────────────
const otherTopics = allTopics.filter(t => t.id !== assignedTopic?.id);
const otherTopics = allTopics.filter(t => t.id !== assignedTopic?.id && t.type !== 'fact');
return (
<div className="p-4 md:p-8 max-w-5xl mx-auto pb-24 md:pb-8 animate-in fade-in duration-300">
<div className="mb-10">
<h1 className="text-3xl md:text-4xl font-bold text-teal mb-3">Learning Station</h1>
<p className="text-fg-muted text-lg">
You must complete at least 1 topic per week. Feel free to explore more or create your own!
You must complete at least 1 topic per week. Feel free to explore more from the library!
</p>
</div>
@@ -229,27 +229,7 @@ const Leren = () => {
</div>
)}
{/* Create Custom Topic */}
<div className="mb-12">
<h2 className="text-xl font-bold mb-4">Explore Something New</h2>
<Card className="border border-bg-warm bg-paper">
<form onSubmit={handleCreateCustom} className="flex flex-col md:flex-row gap-4">
<div className="flex-1">
<Input
placeholder="What do you want to learn about today? (e.g. Advanced Git Workflows)"
value={customTopicQuery}
onChange={e => setCustomTopicQuery(e.target.value)}
/>
</div>
<Button type="submit" disabled={!customTopicQuery.trim() || isLoading} className="flex-shrink-0">
<Plus size={18} className="mr-2" /> Generate Topic
</Button>
</form>
<p className="text-xs text-fg-muted mt-3 flex items-center gap-1">
<BookOpen size={12}/> The AI will instantly build a new learning module for anything you type.
</p>
</Card>
</div>
{/* Other Available Topics */}
{otherTopics.length > 0 && (