Skip to content

Commit 71f45a3

Browse files
committed
ai-test without exposed api key xD
1 parent 6ea14b4 commit 71f45a3

2 files changed

Lines changed: 384 additions & 0 deletions

File tree

project/ai-test.html

Lines changed: 383 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,383 @@
1+
<!DOCTYPE html>
2+
<html lang="de">
3+
<head>
4+
<title>HTML AI Test - KiberOne</title>
5+
<meta charset="UTF-8" />
6+
<meta name="viewport" content="width=device-width" />
7+
<link rel="stylesheet" href="styles.css" />
8+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
9+
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap" rel="stylesheet">
10+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" />
11+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
12+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-markup.min.js"></script>
13+
<style>
14+
/* Bestehende Styles bleiben unverändert */
15+
.chat-container {
16+
display: flex;
17+
flex-direction: column;
18+
gap: 20px;
19+
height: 400px;
20+
overflow-y: auto;
21+
padding: 20px;
22+
background: var(--bg-secondary);
23+
border-radius: 8px;
24+
border: 1px solid var(--border-color);
25+
margin-bottom: 20px;
26+
}
27+
28+
.chat-message {
29+
display: flex;
30+
gap: 15px;
31+
max-width: 80%;
32+
}
33+
34+
.chat-message.user {
35+
margin-left: auto;
36+
flex-direction: row-reverse;
37+
}
38+
39+
.chat-message.ai {
40+
margin-right: auto;
41+
}
42+
43+
.message-content {
44+
padding: 15px;
45+
border-radius: 12px;
46+
background: var(--bg-primary);
47+
border: 1px solid var(--border-color);
48+
}
49+
50+
.user .message-content {
51+
background: var(--accent-color);
52+
color: white;
53+
}
54+
55+
.user .message-content pre {
56+
background: rgba(0, 0, 0, 0.2);
57+
border-radius: 4px;
58+
padding: 10px;
59+
margin: 10px 0;
60+
overflow-x: auto;
61+
}
62+
63+
.ai .message-content {
64+
background: var(--bg-primary);
65+
}
66+
67+
.code-editor {
68+
width: 100%;
69+
margin-top: 20px;
70+
display: flex;
71+
gap: 20px;
72+
}
73+
74+
.editor-section {
75+
flex: 1;
76+
}
77+
78+
.code-input {
79+
width: 100%;
80+
min-height: 300px;
81+
padding: 15px;
82+
font-family: 'Fira Code', monospace;
83+
font-size: 14px;
84+
line-height: 1.5;
85+
background: var(--code-bg);
86+
color: var(--code-text);
87+
border: 1px solid var(--border-color);
88+
border-radius: 8px;
89+
resize: vertical;
90+
}
91+
92+
.preview-section {
93+
flex: 1;
94+
border: 1px solid var(--border-color);
95+
border-radius: 8px;
96+
padding: 15px;
97+
background: white;
98+
}
99+
100+
.task-description {
101+
background: var(--bg-primary);
102+
padding: 15px;
103+
border-radius: 8px;
104+
margin-bottom: 20px;
105+
border-left: 4px solid var(--accent-color);
106+
}
107+
108+
.controls {
109+
display: flex;
110+
gap: 10px;
111+
margin-top: 15px;
112+
}
113+
114+
.preview-btn,
115+
.submit-btn {
116+
padding: 10px 20px;
117+
border: none;
118+
border-radius: 6px;
119+
cursor: pointer;
120+
font-weight: 500;
121+
transition: all 0.3s ease;
122+
}
123+
124+
.preview-btn {
125+
background: var(--bg-primary);
126+
color: var(--text-primary);
127+
border: 1px solid var(--border-color);
128+
}
129+
130+
.submit-btn {
131+
background: var(--accent-color);
132+
color: white;
133+
}
134+
135+
.preview-btn:hover,
136+
.submit-btn:hover {
137+
transform: translateY(-2px);
138+
}
139+
140+
.submit-btn:hover {
141+
background: var(--accent-hover);
142+
}
143+
144+
/* Verbesserte Task Selector Styles */
145+
.task-selector {
146+
margin-bottom: 20px;
147+
}
148+
149+
.task-selector label {
150+
display: block;
151+
margin-bottom: 8px;
152+
color: var(--text-primary);
153+
font-weight: 500;
154+
}
155+
156+
.task-selector select {
157+
padding: 8px 12px;
158+
border-radius: 6px;
159+
border: 1px solid var(--border-color);
160+
background: var(--bg-secondary);
161+
color: var(--text-primary);
162+
font-size: 1em;
163+
width: 100%;
164+
max-width: 400px;
165+
}
166+
</style>
167+
</head>
168+
<body>
169+
<nav>
170+
<a href="/" class="logo">
171+
<img src="../logo.png" alt="Logo" height="40">
172+
</a>
173+
<a href="/">Startseite</a>
174+
<a href="/html.html">HTML Tutorial</a>
175+
<a href="/css.html">CSS Tutorial</a>
176+
<a href="/aufgaben.html">Aufgaben</a>
177+
<a href="/quiz.html">Quiz</a>
178+
<a href="/ai-test.html" aria-current="page">AI Test</a>
179+
</nav>
180+
181+
<main>
182+
<div class="container">
183+
<h1>HTML AI Test</h1>
184+
<p>Übe HTML mit KI-Unterstützung. Die KI hilft dir Schritt für Schritt, deinen Code zu verbessern.</p>
185+
186+
<div class="task-selector">
187+
<label for="taskSelect">Wähle eine Übungsaufgabe:</label>
188+
<select id="taskSelect" aria-label="Übungsaufgabe auswählen">
189+
<option value="">Bitte wähle eine Aufgabe...</option>
190+
<option value="basic">Einfache HTML-Seite</option>
191+
<option value="form">Kontaktformular</option>
192+
<option value="nav">Navigationsleiste</option>
193+
<option value="gallery">Bildergalerie</option>
194+
<option value="semantic">Semantisches Layout</option>
195+
</select>
196+
</div>
197+
198+
<div class="task-description" id="taskDescription"></div>
199+
<div class="chat-container" id="chatContainer"></div>
200+
201+
<div class="code-editor">
202+
<div class="editor-section">
203+
<h3>HTML Code</h3>
204+
<textarea id="codeInput" class="code-input" placeholder="Schreibe deinen HTML-Code hier..." spellcheck="false" aria-label="HTML Code Editor"></textarea>
205+
<div class="controls">
206+
<button id="submitBtn" class="submit-btn">Code einreichen</button>
207+
</div>
208+
</div>
209+
<div class="preview-section">
210+
<h3>Vorschau</h3>
211+
<div id="codePreview" aria-live="polite"></div>
212+
</div>
213+
</div>
214+
</div>
215+
</main>
216+
217+
<script>
218+
// JavaScript-Code bleibt unverändert
219+
const tasks = {
220+
basic: {
221+
title: "Einfache HTML-Seite",
222+
description: "Erstelle eine HTML-Seite mit:\n- Einer Überschrift 'Meine erste Webseite'\n- Einem Absatz mit dem Text 'Willkommen auf meiner Webseite!'"
223+
},
224+
form: {
225+
title: "Kontaktformular",
226+
description: "Erstelle ein Formular mit:\n- Eingabefeldern für Name und Email\n- Einer Textarea für die Nachricht\n- Einem Submit-Button"
227+
},
228+
nav: {
229+
title: "Navigationsleiste",
230+
description: "Erstelle eine Navigationsleiste mit:\n- Mindestens 3 Links\n- Verwende das nav-Element\n- Strukturiere die Links als Liste"
231+
},
232+
gallery: {
233+
title: "Bildergalerie",
234+
description: "Baue eine Bildergalerie mit:\n- Grid oder Flexbox Layout\n- Mindestens 4 Bildern\n- Responsivem Design"
235+
},
236+
semantic: {
237+
title: "Semantisches Layout",
238+
description: "Erstelle ein Layout mit:\n- Header, Nav, Main, Aside und Footer\n- Sinnvoller Verschachtelung\n- Semantisch korrekter Struktur"
239+
}
240+
};
241+
242+
async function evaluateCode(task, code, conversation = []) {
243+
const prompt = `
244+
Als HTML-Tutor, bewerte bitte den folgenden Code für diese Aufgabe:
245+
246+
Aufgabe: ${task}
247+
Code:
248+
${code}
249+
250+
Bisheriger Chatverlauf:
251+
${conversation.map(msg => `${msg.role}: ${msg.content}`).join('\n')}
252+
253+
Gib konstruktives Feedback und Verbesserungsvorschläge. Wenn der Code noch nicht perfekt ist,
254+
führe den Schüler mit Hinweisen zur richtigen Lösung. Antworte im Format:
255+
{
256+
"completed": true/false,
257+
"feedback": "Dein detailliertes Feedback hier",
258+
"hint": "Ein hilfreicher Tipp (nur wenn noch nicht completed)"
259+
}
260+
`;
261+
262+
try {
263+
const response = await fetch('https://api.mistral.ai/v1/chat/completions', {
264+
method: 'POST',
265+
headers: {
266+
'Content-Type': 'application/json',
267+
'Authorization': 'Bearer zh7CfBXRcIXgoOdBobNIhv5zctjJCGez'
268+
},
269+
body: JSON.stringify({
270+
model: "mistral-tiny",
271+
messages: [
272+
{
273+
role: "user",
274+
content: prompt
275+
}
276+
],
277+
response_format: { type: "json_object" }
278+
})
279+
});
280+
281+
const data = await response.json();
282+
return JSON.parse(data.choices[0].message.content);
283+
} catch (error) {
284+
console.error('Fehler bei der API-Anfrage:', error);
285+
return {
286+
completed: false,
287+
feedback: 'Es gab einen Fehler bei der Bewertung. Bitte versuche es erneut.',
288+
hint: 'Versuche es später noch einmal.'
289+
};
290+
}
291+
}
292+
293+
// Event Listener
294+
document.addEventListener('DOMContentLoaded', () => {
295+
const taskSelect = document.getElementById('taskSelect');
296+
const taskDescription = document.getElementById('taskDescription');
297+
const codeInput = document.getElementById('codeInput');
298+
const submitBtn = document.getElementById('submitBtn');
299+
const previewBox = document.getElementById('codePreview');
300+
const chatContainer = document.getElementById('chatContainer');
301+
302+
let conversation = [];
303+
304+
// Live Preview
305+
codeInput.addEventListener('input', () => {
306+
previewBox.innerHTML = codeInput.value;
307+
Prism.highlightElement(codeInput);
308+
});
309+
310+
taskSelect.addEventListener('change', (e) => {
311+
const task = tasks[e.target.value];
312+
if (task) {
313+
taskDescription.innerHTML = `
314+
<h3>${task.title}</h3>
315+
<p>${task.description.replace(/\n/g, '<br>')}</p>
316+
`;
317+
chatContainer.innerHTML = '';
318+
conversation = [];
319+
320+
// Füge erste KI-Nachricht hinzu
321+
const messageDiv = document.createElement('div');
322+
messageDiv.className = 'chat-message ai';
323+
messageDiv.innerHTML = `
324+
<div class="message-content">
325+
<p>Ich bin bereit, dir bei der Aufgabe "${task.title}" zu helfen! Schreibe deinen Code in den Editor und ich gebe dir Feedback dazu.</p>
326+
</div>
327+
`;
328+
chatContainer.appendChild(messageDiv);
329+
}
330+
});
331+
332+
submitBtn.addEventListener('click', async () => {
333+
const code = codeInput.value;
334+
const task = tasks[taskSelect.value];
335+
336+
if (!task) {
337+
alert('Bitte wähle zuerst eine Aufgabe aus.');
338+
return;
339+
}
340+
341+
// Benutzer-Code zum Chat hinzufügen
342+
const userMessageDiv = document.createElement('div');
343+
userMessageDiv.className = 'chat-message user';
344+
userMessageDiv.innerHTML = `
345+
<div class="message-content">
346+
<p>Hier ist mein Code:</p>
347+
<pre><code class="language-html">${code}</code></pre>
348+
</div>
349+
`;
350+
chatContainer.appendChild(userMessageDiv);
351+
352+
// Code an Mistral API senden
353+
const result = await evaluateCode(task.description, code, conversation);
354+
355+
// Konversation aktualisieren
356+
conversation.push({ role: 'user', content: code });
357+
conversation.push({ role: 'assistant', content: result.feedback });
358+
359+
// KI-Antwort zum Chat hinzufügen
360+
const aiMessageDiv = document.createElement('div');
361+
aiMessageDiv.className = 'chat-message ai';
362+
aiMessageDiv.innerHTML = `
363+
<div class="message-content">
364+
<p>${result.feedback}</p>
365+
${result.hint ? `<p><strong>Tipp:</strong> ${result.hint}</p>` : ''}
366+
${result.completed ? '<p><strong>🎉 Super! Du hast die Aufgabe erfolgreich gelöst!</strong></p>' : ''}
367+
</div>
368+
`;
369+
chatContainer.appendChild(aiMessageDiv);
370+
371+
// Zum Ende scrollen
372+
chatContainer.scrollTop = chatContainer.scrollHeight;
373+
374+
// Code-Highlighting aktualisieren
375+
Prism.highlightAll();
376+
});
377+
});
378+
</script>
379+
<footer>
380+
<a href="https://github.com/vsvito420" target="_blank" rel="noopener">GitHub: vsvito420</a>
381+
</footer>
382+
</body>
383+
</html>

project/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<a href="/css.html">CSS Tutorial</a>
1919
<a href="/aufgaben.html">Aufgaben</a>
2020
<a href="/quiz.html">Quiz</a>
21+
<a href="/ai-test.html">AI Test</a>
2122
<a href="/zusammenfassung.html">Zusammenfassung</a>
2223
</nav>
2324

0 commit comments

Comments
 (0)