Virtueller Nachhilfe-Chat – Dein persönlicher Lernassistent
Mit diesem Dreamcodes Script erhältst du einen professionell gestalteten Chat, in dem ein virtueller Nachhilfelehrer deine Fragen beantwortet. Der Chat ist speziell für Schüler und Lernende zugeschnitten und vermittelt Inhalte so, als würdest du direkt mit einem erfahrenen Lehrer mit über 30 Jahren Unterrichtspraxis sprechen.
Funktionen:
- Echtzeit-Chat mit GPT-API-Anbindung – Antworten werden live generiert
- Verständliche, ausführliche Erklärungen zu Themen wie Mathematik, Deutsch, Englisch, Naturwissenschaften und mehr
- Chronologischer Sitzungsverlauf – jede Frage und Antwort bleibt im Verlauf gespeichert
- Professionelles, schülerfreundliches Design – klare Darstellung, leicht zu bedienen
- Speicherung in SQLite – kein komplizierter Setup nötig
- Hinweise und Tipps für effektives Lernen – unterstützt Motivation und Prüfungsvorbereitung
Vorteile:
- Persönliche Nachhilfe rund um die Uhr
- Ideal für Hausaufgaben, Wiederholungen und Prüfungsvorbereitung
- Hilft, komplizierte Themen leicht verständlich zu machen
- Spart Zeit und bietet jederzeit schnelle Unterstützung
Hinweis:
Der virtuelle Nachhilfe-Chat ersetzt keinen menschlichen Lehrer im klassischen Sinne, bietet aber eine flexible, digitale Ergänzung für effektives Lernen.
<?php
define('DB_FILE', __DIR__ . '/tutor_chat.sqlite');
define('OPENAI_API_KEY', 'DEIN_OPENAI_API_KEY_HIER');
$db = new SQLite3(DB_FILE);
$db->exec("CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY,
role TEXT,
message TEXT,
meta TEXT,
created_at INTEGER
)");
function jsonResponse($data,$code=200){
http_response_code($code);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit;
}
function escape($s){ return htmlspecialchars($s, ENT_QUOTES, 'utf-8'); }
function callGPT($userMessage, $subject = '', $level = ''){
$system = "Du bist ein geduldiger und erfahrener Nachhilfelehrer mit jahrzehntelanger Unterrichtspraxis. Antworte klar, strukturiert und schülergerecht. Gib schrittweise Erklärungen, Beispiele, kurze Übungsaufgaben mit Lösungen auf Anfrage sowie Lernstrategien. Passe Sprache und Beispiele dem Schulniveau an (GMS / Realschule / Gymnasium / Abitur / Uni). Kennzeichne Abschnitte mit Überschriften: Zusammenfassung, Schritt für Schritt Erklärung, Beispiel, Übungsaufgabe (optional), Lernhinweise. Wecke Motivation, frage mehrfach das Verständnis ab und schlage weiterführende Ressourcen oder Hausaufgaben vor. Vermeide medizinische, rechtliche oder sicherheitsrelevante Anweisungen."
;
$preface = "Fach: " . ($subject ?: 'Allgemein') . ". Niveau: " . ($level ?: 'Schülerniveau 1') . ".\n\n";
$payload = [
'model' => 'gpt-4',
'messages' => [
['role'=>'system','content'=>$system],
['role'=>'user','content'=>$preface . $userMessage]
],
'max_tokens' => 900,
'temperature' => 0.2
];
$ch = curl_init('https://api.openai.com/v1/chat/completions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer '.OPENAI_API_KEY
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
$resp = curl_exec($ch);
if(curl_errno($ch)){
curl_close($ch);
return 'Fehler: ' . curl_error($ch);
}
curl_close($ch);
$data = json_decode($resp, true);
return $data['choices'][0]['message']['content'] ?? 'Fehler bei der Antwortgenerierung';
}
// Handle send
if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['action']) && $_GET['action'] === 'send'){
$msg = trim($_POST['message'] ?? '');
$subject = trim($_POST['subject'] ?? '');
$level = trim($_POST['level'] ?? '');
if(!$msg) jsonResponse(['error' => 'Keine Nachricht eingegeben'], 400);
$stmt = $db->prepare('INSERT INTO messages (role,message,meta,created_at) VALUES (:role,:message,:meta,:created_at)');
$stmt->bindValue(':role','user',SQLITE3_TEXT);
$stmt->bindValue(':message',$msg,SQLITE3_TEXT);
$stmt->bindValue(':meta',json_encode(['subject'=>$subject,'level'=>$level], JSON_UNESCAPED_UNICODE),SQLITE3_TEXT);
$stmt->bindValue(':created_at',time(),SQLITE3_INTEGER);
$stmt->execute();
$reply = callGPT($msg, $subject, $level);
$stmt2 = $db->prepare('INSERT INTO messages (role,message,meta,created_at) VALUES (:role,:message,:meta,:created_at)');
$stmt2->bindValue(':role','tutor',SQLITE3_TEXT);
$stmt2->bindValue(':message',$reply,SQLITE3_TEXT);
$stmt2->bindValue(':meta',json_encode(['subject'=>$subject,'level'=>$level], JSON_UNESCAPED_UNICODE),SQLITE3_TEXT);
$stmt2->bindValue(':created_at',time(),SQLITE3_INTEGER);
$stmt2->execute();
jsonResponse(['reply'=>$reply]);
}
// History
if(isset($_GET['action']) && $_GET['action'] === 'history'){
$res = $db->query('SELECT * FROM messages ORDER BY created_at ASC');
$out = [];
while($row = $res->fetchArray(SQLITE3_ASSOC)){
$out[] = [
'role' => $row['role'],
'message' => $row['message'],
'meta' => json_decode($row['meta'] ?: '{}', true),
'time' => date('d.m.Y H:i', $row['created_at'])
];
}
jsonResponse($out);
}
// Serve UI
?><!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Virtueller Dreamcodes Nachhilfelehrer</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
<style>
:root{--bg:#0f1724;--card:#0b1220;--accent:#06b6d4;--muted:#9aa4b2;--glass: rgba(255,255,255,0.03);} body{font-family:Inter,system-ui,Arial;background:linear-gradient(180deg,var(--bg),#071028);color:#e6eef8;margin:0;padding:36px;}
.container{max-width:980px;margin:0 auto}
.header{display:flex;justify-content:space-between;align-items:center;margin-bottom:18px}
.title{font-size:22px;font-weight:700}
.subtitle{color:var(--muted);font-size:14px}
.card{background:linear-gradient(180deg,var(--card),#071022);padding:20px;border-radius:14px;box-shadow:0 8px 22px rgba(2,6,23,0.7)}
.form-row{display:flex;gap:12px;margin-bottom:12px}
.select, .input, textarea{background:transparent;border:1px solid rgba(255,255,255,0.04);padding:10px;border-radius:8px;color:inherit}
textarea{min-height:120px;resize:vertical}
.btn{background:var(--accent);color:#042a2f;padding:10px 14px;border-radius:10px;border:none;cursor:pointer;font-weight:700}
.chat{margin-top:18px}
.msg{padding:12px;border-radius:10px;margin-bottom:10px;background:rgba(255,255,255,0.02)}
.msg.user{border-left:4px solid rgba(124,58,237,0.8)}
.msg.tutor{border-left:4px solid rgba(6,182,212,0.9);background:linear-gradient(180deg, rgba(6,182,212,0.04), rgba(6,182,212,0.02))}
.meta{font-size:12px;color:var(--muted);margin-bottom:8px}
.footer{margin-top:14px;text-align:center;color:var(--muted);font-size:13px}
.small{font-size:12px;color:var(--muted)}
</style>
</head>
<body>
<div class="container">
<div class="header">
<div>
<div class="title">Virtueller Nachhilfelehrer</div>
<div class="subtitle">Schülergerechte Erklärungen, Übungen und Lernstrategien</div>
</div>
<div class="small">Powered by Dreamcodes.NET</div>
</div>
<div class="card">
<div class="form-row">
<select id="subject" class="select" style="min-width:220px">
<option value="">Fach wählen oder frei lassen</option>
<option>Mathematik</option>
<option>Physik</option>
<option>Chemie</option>
<option>Biologie</option>
<option>Deutsch</option>
<option>Englisch</option>
<option>Geschichte</option>
<option>Informatik</option>
</select>
<select id="level" class="select" style="min-width:220px">
<option value="">Niveau wählen</option>
<option>Grundschule</option>
<option>Weiterführende Schule</option>
<option>Gymnasium / Abitur</option>
<option>Studium</option>
</select>
</div>
<textarea id="userMsg" placeholder="Stelle deine Frage oder beschreibe dein Problem..." class="input"></textarea>
<div style="display:flex;gap:10px;margin-top:10px;align-items:center">
<button id="sendBtn" class="btn">Frage stellen</button>
<button id="practiceBtn" class="btn" style="background:#8b5cf6">Übungsaufgabe anfordern</button>
<div class="small">Tipp: Sei so konkret wie möglich, z. B. Thema, Kapitel, Beispielaufgabe</div>
</div>
</div>
<div class="chat card" id="chat"></div>
<div class="footer">Hinweis: Der Chat ersetzt keine persönliche Nachhilfe. Für verbindliche Prüfungsberatung empfehlen wir Kontakt zu Lehrkräften.</div>
</div>
<script>
async function fetchHistory(){
const r = await fetch('?action=history');
const data = await r.json();
const chat = document.getElementById('chat');
chat.innerHTML = '';
data.forEach(m => {
const el = document.createElement('div');
el.className = 'msg ' + (m.role === 'user' ? 'user' : 'tutor');
const meta = `<div class="meta">${m.role === 'user' ? 'Du' : 'Nachhilfelehrer'} · ${m.time}` + (m.meta.subject ? ' · ' + m.meta.subject : '') + (m.meta.level ? ' · ' + m.meta.level : '') + `</div>`;
el.innerHTML = meta + '<div>' + m.message.replace(/\n/g, '<br>') + '</div>';
chat.appendChild(el);
});
chat.scrollTop = chat.scrollHeight;
}
async function sendMessage(practice = false){
const msg = document.getElementById('userMsg').value.trim();
const subject = document.getElementById('subject').value;
const level = document.getElementById('level').value;
if(!msg) return;
let fullMsg = msg;
if(practice) fullMsg += '\n\nBitte: Ergänze eine passende Übungsaufgabe mit Lösung und erkläre die Lösung Schritt für Schritt.';
const fd = new FormData(); fd.append('message', fullMsg); fd.append('subject', subject); fd.append('level', level);
document.getElementById('sendBtn').disabled = true;
document.getElementById('sendBtn').textContent = 'Sende...';
try{
const resp = await fetch('?action=send', { method: 'POST', body: fd });
const data = await resp.json();
if(data.error){ alert(data.error); }
else{ document.getElementById('userMsg').value = ''; fetchHistory(); }
}catch(e){ alert('Netzwerkfehler'); }
document.getElementById('sendBtn').disabled = false;
document.getElementById('sendBtn').textContent = 'Frage stellen';
}
document.getElementById('sendBtn').addEventListener('click', ()=> sendMessage(false));
document.getElementById('practiceBtn').addEventListener('click', ()=> sendMessage(true));
fetchHistory();
</script>
</body>
</html>