Baue ein Second Brain: Persönliches Wissensmanagementsystem
Von Wikiprompt, der freien Prompt-Enzyklopädie
Baue ein Second Brain: Persönliches Wissensmanagementsystem Ein umfassender Prompt zur Erstellung eines einseitigen persönlichen Wissensmanagementsystems mit Notizen, Aufgaben, Projekten und Verbindungen, alles in localStorage gespeichert.
Prompt-InhaltSpeichern
🌐
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Second Brain · PKM</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--bg: #f8f9fb; --surface: #ffffff; --text: #1e293b; --muted: #64748b;
--border: #e2e8f0; --primary: #4f46e5; --primary-soft: #eef2ff;
--accent: #0ea5e9; --success: #10b981; --warning: #f59e0b; --danger: #ef4444;
--shadow: 0 4px 12px rgba(0,0,0,0.04); --radius: 14px;
}
body.dark {
--bg: #0f172a; --surface: #1e293b; --text: #e2e8f0; --muted: #94a3b8;
--border: #334155; --primary: #818cf8; --primary-soft: #1e1b4b;
--shadow: 0 4px 12px rgba(0,0,0,0.3);
}
body { font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; background: var(--bg); color: var(--text); transition: background 0.3s, color 0.3s; }
.app { display: flex; height: 100vh; overflow: hidden; }
/* sidebar */
.sidebar { width: 240px; background: var(--surface); border-right: 1px solid var(--border); padding: 1.2rem 0.8rem; display: flex; flex-direction: column; gap: 0.3rem; }
.sidebar .logo { font-weight: 700; font-size: 1.3rem; padding: 0.5rem 0.8rem 1.2rem; letter-spacing: -0.02em; }
.sidebar .logo span { color: var(--primary); }
.nav-item { display: flex; align-items: center; gap: 0.7rem; padding: 0.6rem 0.8rem; border-radius: 10px; color: var(--muted); font-weight: 500; cursor: pointer; transition: 0.15s; }
.nav-item:hover { background: var(--primary-soft); color: var(--primary); }
.nav-item.active { background: var(--primary); color: white; }
.nav-item i { width: 20px; text-align: center; }
/* main */
.main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
.topbar { height: 60px; background: var(--surface); border-bottom: 1px solid var(--border); display: flex; align-items: center; padding: 0 1.5rem; gap: 1rem; }
.topbar .search { flex: 1; max-width: 380px; background: var(--bg); border: 1px solid var(--border); border-radius: 30px; padding: 0.5rem 1rem; display: flex; align-items: center; gap: 0.5rem; }
.topbar .search input { border: none; background: transparent; width: 100%; outline: none; color: var(--text); }
.icon-btn { background: var(--bg); border: 1px solid var(--border); border-radius: 30px; padding: 0.45rem 0.9rem; cursor: pointer; font-weight: 500; display: flex; align-items: center; gap: 0.4rem; transition: 0.15s; }
.icon-btn:hover { background: var(--primary-soft); border-color: var(--primary); }
.content { flex: 1; overflow-y: auto; padding: 2rem 2rem 3rem; }
/* cards */
.grid-dash { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.2rem; margin-bottom: 2rem; }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.2rem; box-shadow: var(--shadow); }
.card h3 { font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); margin-bottom: 0.8rem; }
.stat { font-size: 2rem; font-weight: 700; }
.stat-label { color: var(--muted); font-size: 0.85rem; }
.prompt-box { background: var(--primary-soft); border-left: 4px solid var(--primary); padding: 1.2rem; border-radius: 12px; margin-bottom: 2rem; display: flex; justify-content: space-between; align-items: center; }
.prompt-box input { background: transparent; border: none; border-bottom: 2px dashed var(--primary); padding: 0.4rem 0; font-size: 1rem; width: 70%; outline: none; color: var(--text); }
.btn { background: var(--primary); color: white; border: none; padding: 0.5rem 1.2rem; border-radius: 30px; font-weight: 500; cursor: pointer; transition: 0.15s; }
.btn-outline { background: transparent; border: 1px solid var(--border); color: var(--text); }
.btn-outline:hover { background: var(--bg); }
.tag { background: var(--primary-soft); color: var(--primary); padding: 0.2rem 0.7rem; border-radius: 30px; font-size: 0.75rem; font-weight: 500; }
.item-row { display: flex; justify-content: space-between; align-items: center; padding: 0.7rem 0; border-bottom: 1px solid var(--border); }
.item-row:last-child { border-bottom: none; }
.muted { color: var(--muted); font-size: 0.85rem; }
.progress { height: 6px; background: var(--border); border-radius: 10px; margin: 0.5rem 0; }
.progress-bar { height: 6px; background: var(--success); border-radius: 10px; width: 0%; }
.flex { display: flex; gap: 0.8rem; align-items: center; }
.float-btn { position: fixed; bottom: 2rem; right: 2rem; background: var(--primary); color: white; width: 56px; height: 56px; border-radius: 30px; display: flex; align-items: center; justify-content: center; font-size: 1.8rem; box-shadow: 0 8px 20px rgba(79,70,229,0.3); cursor: pointer; border: none; z-index: 100; }
.modal { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: none; align-items: center; justify-content: center; z-index: 200; }
.modal.show { display: flex; }
.modal-card { background: var(--surface); border-radius: 20px; padding: 2rem; width: 90%; max-width: 500px; box-shadow: 0 20px 40px rgba(0,0,0,0.2); }
.modal-card input, .modal-card textarea, .modal-card select { width: 100%; padding: 0.7rem; border: 1px solid var(--border); border-radius: 10px; margin-bottom: 1rem; background: var(--bg); color: var(--text); }
.modal-card h2 { margin-bottom: 1.2rem; }
.hidden { display: none; }
.map-container { background: var(--surface); border-radius: var(--radius); padding: 1.5rem; border: 1px solid var(--border); }
.map-node { display: inline-block; background: var(--primary-soft); padding: 0.3rem 0.8rem; border-radius: 30px; margin: 0.3rem; font-size: 0.85rem; }
</style>
</head>
<body>
<div class="app">
<!-- SIDEBAR -->
<aside class="sidebar" id="sidebar">
<div class="logo">⚡ <span>second</span>brain</div>
<div class="nav-item active" data-view="dashboard"><i>🏠</i> Dashboard</div>
<div class="nav-item" data-view="inbox"><i>📥</i> Inbox</div>
<div class="nav-item" data-view="notes"><i>📝</i> Notes</div>
<div class="nav-item" data-view="projects"><i>📁</i> Projects</div>
<div class="nav-item" data-view="tasks"><i>✅</i> Tasks</div>
<div class="nav-item" data-view="map"><i>🕸️</i> Map</div>
<div class="nav-item" data-view="settings"><i>⚙️</i> Settings</div>
</aside>
<!-- MAIN -->
<div class="main">
<div class="topbar">
<div class="search"><span>🔍</span><input placeholder="Search notes, tasks, projects..." id="globalSearch"></div>
<button class="icon-btn" id="quickAddBtn">➕ Quick add</button>
<button class="icon-btn" id="themeToggle">🌙</button>
</div>
<div class="content" id="contentArea">
<!-- dynamic views injected -->
</div>
</div>
</div>
<!-- floating quick add -->
<button class="float-btn" id="floatAdd">+</button>
<!-- modal for quick add -->
<div class="modal" id="quickModal">
<div class="modal-card">
<h2>⚡ Quick capture</h2>
<input type="text" id="quickTitle" placeholder="Title (note, task, idea)">
<textarea id="quickDesc" rows="2" placeholder="Description (optional)"></textarea>
<select id="quickType">
<option value="note">Note</option>
<option value="task">Task</option>
<option value="idea">Idea</option>
</select>
<div class="flex" style="justify-content: flex-end;">
<button class="btn-outline" style="padding:0.5rem 1rem;" onclick="closeModal()">Cancel</button>
<button class="btn" onclick="saveQuick()">Save</button>
</div>
</div>
</div>
<script>
// ---------- DATA LAYER (localStorage) ----------
const DEFAULT_DATA = {
notes: [
{ id: 'n1', title: 'Welcome note', content: 'This is your second brain. Capture everything.', tags: ['intro'], project: 'p1', created: Date.now(), modified: Date.now(), versions: ['This is your second brain. Capture everything.'] },
{ id: 'n2', title: 'Meeting with team', content: 'Discuss Q3 roadmap.', tags: ['work'], project: 'p1', created: Date.now()-86400000, modified: Date.now()-3600000, versions: ['Discuss Q3 roadmap.'] }
],
tasks: [
{ id: 't1', title: 'Review quarterly goals', description: '', due: Date.now()+86400000, priority: 'High', project: 'p1', done: false, subtasks: [], recurring: 'none' },
{ id: 't2', title: 'Write blog post', description: 'Draft outline', due: Date.now()+172800000, priority: 'Medium', project: 'p2', done: false, subtasks: [], recurring: 'none' }
],
projects: [
{ id: 'p1', name: 'Second Brain', description: 'Build PKM system', status: 'Active', deadline: Date.now()+86400000*10, progress: 60 },
{ id: 'p2', name: 'Content Creation', description: 'Blog & newsletter', status: 'Active', deadline: Date.now()+86400000*20, progress: 30 }
],
ideas: [
{ id: 'i1', title: 'Automate weekly review', tags: ['automation'], project: 'p1', created: Date.now() }
],
activity: [
{ text: 'Created note "Welcome note"', time: Date.now() },
{ text: 'Completed task "Review goals"', time: Date.now()-3600000 }
]
};
let DB = loadData();
function loadData() {
const stored = localStorage.getItem('secondbrain_data');
if (stored) { try { return JSON.parse(stored); } catch(e) {} }
return JSON.parse(JSON.stringify(DEFAULT_DATA));
}
function saveData() {
localStorage.setItem('secondbrain_data', JSON.stringify(DB));
}
// ---------- STATE ----------
let currentView = 'dashboard';
let searchTerm = '';
// ---------- DOM ELEMENTS ----------
const contentArea = document.getElementById('contentArea');
const sidebarItems = document.querySelectorAll('.nav-item');
const themeToggle = document.getElementById('themeToggle');
const quickModal = document.getElementById('quickModal');
const globalSearch = document.getElementById('globalSearch');
// ---------- HELPERS ----------
function formatDate(ts) {
return new Date(ts).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
}
function getProjectName(id) {
const p = DB.projects.find(x => x.id === id);
return p ? p.name : '-';
}
function countTasks() { return DB.tasks.filter(t => t.done).length + '/' + DB.tasks.length; }
function activeProjects() { return DB.projects.filter(p => p.status === 'Active').length; }
// ---------- RENDER ----------
function render() {
if (currentView === 'dashboard') renderDashboard();
else if (currentView === 'inbox') renderInbox();
else if (currentView === 'notes') renderNotes();
else if (currentView === 'projects') renderProjects();
else if (currentView === 'tasks') renderTasks();
else if (currentView === 'map') renderMap();
else if (currentView === 'settings') renderSettings();
saveData();
}
function renderDashboard() {
const todayTasks = DB.tasks.filter(t => !t.done && new Date(t.due).toDateString() === new Date().toDateString());
const recentNotes = [...DB.notes].sort((a,b) => b.modified - a.modified).slice(0,3);
const activeProj = DB.projects.filter(p => p.status === 'Active');
const totalNotes = DB.notes.length;
const doneTasks = DB.tasks.filter(t => t.done).length;
let html = `
<div class="prompt-box">
<span style="font-weight:600;">💭 "What's one thing you want to remember today?"</span>
<input type="text" placeholder="Write it down..." id="dailyPromptInput">
</div>
<div class="grid-dash">
<div class="card"><h3>📌 Today's tasks</h3>${todayTasks.length ? todayTasks.map(t=>`<div class="item-row"><span>${t.title}</span><span class="tag">${t.priority}</span></div>`).join('') : '<span class="muted">Nothing due today</span>'}</div>
<div class="card"><h3>📝 Recent notes</h3>${recentNotes.map(n=>`<div class="item-row"><span>${n.title}</span><span class="muted">${formatDate(n.modified)}</span></div>`).join('')}</div>
<div class="card"><h3>📁 Active projects</h3>${activeProj.map(p=>`<div class="item-row"><span>${p.name}</span><span class="tag">${p.status}</span></div>`).join('')}</div>
<div class="card"><h3>📊 Stats</h3><div class="stat">${totalNotes}</div><div class="stat-label">notes</div><div class="stat" style="font-size:1.4rem;">${doneTasks}/${DB.tasks.length}</div><div class="stat-label">tasks done</div><div class="stat" style="font-size:1.4rem;">${activeProjects()}</div><div class="stat-label">active projects</div></div>
</div>
<div class="card"><h3>🕒 Activity feed</h3>${DB.activity.slice(0,5).map(a=>`<div class="item-row"><span>${a.text}</span><span class="muted">${formatDate(a.time)}</span></div>`).join('')}</div>
`;
contentArea.innerHTML = html;
// daily prompt listener
const promptInput = document.getElementById('dailyPromptInput');
if (promptInput) promptInput.addEventListener('change', (e) => {
if (e.target.value.trim()) {
DB.activity.unshift({ text: `Daily prompt: "${e.target.value}"`, time: Date.now() });
e.target.value = '';
saveData(); render();
}
});
}
function renderInbox() {
let html = `<h2 style="margin-bottom:1rem;">📥 Inbox & ideas</h2><div class="card">`;
DB.ideas.forEach(idea => {
html += `<div class="item-row"><span>💡 ${idea.title}</span><span class="tag">${idea.tags.join(', ') || 'idea'}</span></div>`;
});
html += `</div><div style="margin-top:1rem;"><button class="btn" onclick="quickModal.classList.add('show')">+ capture idea</button></div>`;
contentArea.innerHTML = html;
}
function renderNotes() {
let filtered = DB.notes;
if (searchTerm) {
filtered = filtered.filter(n => n.title.toLowerCase().includes(searchTerm) || n.content.toLowerCase().includes(searchTerm) || n.tags.some(t=>t.includes(searchTerm)));
}
let html = `<div class="flex" style="justify-content:space-between;"><h2>📝 Notes (${filtered.length})</h2><button class="btn" onclick="quickModal.classList.add('show')">+ note</button></div><div style="margin-top:1rem;">`;
filtered.forEach(n => {
html += `<div class="card" style="margin-bottom:1rem;"><div class="flex" style="justify-content:space-between;"><strong>${n.title}</strong><span class="muted">${formatDate(n.modified)}</span></div><p class="muted" style="margin:0.5rem 0;">${n.content.substring(0,80)}...</p><div class="flex">${n.tags.map(t=>`<span class="tag">#${t}</span>`).join('')}<span class="muted">📁 ${getProjectName(n.project)}</span></div></div>`;
});
html += `</div>`;
contentArea.innerHTML = html;
}
function renderProjects() {
let html = `<h2>📁 Projects</h2><div class="grid-dash" style="margin-top:1rem;">`;
DB.projects.forEach(p => {
const progress = p.progress || 0;
html += `<div class="card"><div class="flex" style="justify-content:space-between;"><strong>${p.name}</strong><span class="tag">${p.status}</span></div><p class="muted">${p.description}</p><div class="progress"><div class="progress-bar" style="width:${progress}%"></div></div><span class="muted">${progress}% complete · deadline ${formatDate(p.deadline)}</span></div>`;
});
html += `</div>`;
contentArea.innerHTML = html;
}
function renderTasks() {
let filtered = DB.tasks;
if (searchTerm) filtered = filtered.filter(t => t.title.toLowerCase().includes(searchTerm));
let html = `<div class="flex" style="justify-content:space-between;"><h2>✅ Tasks</h2><button class="btn" onclick="quickModal.classList.add('show')">+ task</button></div><div style="margin-top:1rem;">`;
filtered.forEach(t => {
html += `<div class="card" style="margin-bottom:0.8rem; display:flex; align-items:center; justify-content:space-between;"><div><input type="checkbox" ${t.done?'checked':''} onchange="toggleTask('${t.id}')" style="margin-right:0.6rem;"><strong style="${t.done?'text-decoration:line-through':''}">${t.title}</strong> <span class="muted">· ${t.priority}</span></div><div><span class="tag">${getProjectName(t.project)}</span><span class="muted" style="margin-left:0.5rem;">📅 ${formatDate(t.due)}</span></div></div>`;
});
html += `</div>`;
contentArea.innerHTML = html;
}
function renderMap() {
let html = `<h2>🕸️ Connection map</h2><div class="map-container"><h3>Projects & notes</h3>`;
DB.projects.forEach(p => {
html += `<div style="margin:0.5rem 0;"><span class="tag" style="background:var(--primary); color:white;">📁 ${p.name}</span> → `;
DB.notes.filter(n => n.project === p.id).forEach(n => { html += `<span class="map-node">${n.title}</span> `; });
html += `</div>`;
});
html += `<h3 style="margin-top:1rem;">Ideas</h3>`;
DB.ideas.forEach(i => { html += `<span class="map-node">💡 ${i.title}</span>`; });
html += `</div>`;
contentArea.innerHTML = html;
}
function renderSettings() {
contentArea.innerHTML = `<h2>⚙️ Settings</h2><div class="card"><p><strong>Theme</strong> - use toggle in top bar.</p><p><strong>Data export</strong></p><button class="btn" onclick="exportData()">Export JSON</button> <button class="btn btn-outline" onclick="importData()">Import JSON</button></div>`;
}
// ---------- ACTIONS ----------
function toggleTask(id) {
const task = DB.tasks.find(t => t.id === id);
if (task) { task.done = !task.done; DB.activity.unshift({ text: `${task.done?'Completed':'Reopened'} task "${task.title}"`, time: Date.now() }); saveData(); render(); }
}
function saveQuick() {
const title = document.getElementById('quickTitle').value.trim();
const desc = document.getElementById('quickDesc').value.trim();
const type = document.getElementById('quickType').value;
if (!title) return;
if (type === 'note') {
DB.notes.push({ id: 'n'+Date.now(), title, content: desc || ' ', tags: ['quick'], project: 'p1', created: Date.now(), modified: Date.now(), versions: [desc] });
DB.activity.unshift({ text: `Created note "${title}"`, time: Date.now() });
} else if (type === 'task') {
DB.tasks.push({ id: 't'+Date.now(), title, description: desc, due: Date.now()+86400000, priority: 'Medium', project: 'p1', done: false, subtasks: [], recurring: 'none' });
DB.activity.unshift({ text: `Created task "${title}"`, time: Date.now() });
} else if (type === 'idea') {
DB.ideas.push({ id: 'i'+Date.now(), title, tags: ['idea'], project: 'p1', created: Date.now() });
DB.activity.unshift({ text: `Captured idea "${title}"`, time: Date.now() });
}
saveData(); render(); closeModal();
}
function closeModal() { quickModal.classList.remove('show'); }
function exportData() {
const blob = new Blob([JSON.stringify(DB, null, 2)], { type: 'application/json' });
const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'secondbrain-backup.json'; a.click();
}
function importData() {
const input = document.createElement('input'); input.type = 'file'; input.accept = 'application/json';
input.onchange = e => {
const file = e.target.files[0]; if (!file) return;
const reader = new FileReader();
reader.onload = ev => { try { DB = JSON.parse(ev.target.result); saveData(); render(); } catch(err) { alert('Invalid JSON'); } };
reader.readAsText(file);
};
input.click();
}
// ---------- NAVIGATION & EVENTS ----------
sidebarItems.forEach(item => {
item.addEventListener('click', () => {
sidebarItems.forEach(i => i.classList.remove('active'));
item.classList.add('active');
currentView = item.dataset.view;
render();
});
});
themeToggle.addEventListener('click', () => {
document.body.classList.toggle('dark');
themeToggle.textContent = document.body.classList.contains('dark') ? '☀️' : '🌙';
});
document.getElementById('floatAdd').addEventListener('click', () => quickModal.classList.add('show'));
document.getElementById('quickAddBtn').addEventListener('click', () => quickModal.classList.add('show'));
window.addEventListener('click', (e) => { if (e.target === quickModal) closeModal(); });
globalSearch.addEventListener('input', (e) => {
searchTerm = e.target.value.toLowerCase();
if (currentView === 'notes' || currentView === 'tasks') render();
});
// keyboard shortcut: 'n' for quick add
document.addEventListener('keydown', (e) => {
if (e.key === 'n' && !e.ctrlKey && !e.metaKey) { quickModal.classList.add('show'); }
});
// init
render();
</script>
</body>
</html>
Melde dich an, um den vollständigen Prompt zu sehen
Weiter mit:
Mit der Anmeldung akzeptierst du unsere Nutzungsbedingungen und Datenschutz
Verwendung
Dieser Prompt ist für die Verwendung mit coding gedacht. Kopiere den Inhalt oben und füge ihn in dein bevorzugtes KI-Tool ein.
Für beste Ergebnisse passe die Platzhalter (eckige Klammern oder Großbuchstaben) an deine Anforderungen an.
Referenzen
- Kategorie: coding-Prompts
- Quelle: https://x.com/eyishazyer/status/2073109263514505488
Diskussion
0 Kommentare