2025-11-13 08:53:11 +01:00

183 lines
6.3 KiB
HTML

{{define "main-page"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Interactive HTML Tutorial</title>
<script type="module" src="/datastar.js"></script>
<style>
*{box-sizing:border-box} body{font-family:Inter,system-ui,Segoe UI,Roboto,Arial; background:#f3f6fb; padding:24px}
.container{max-width:900px;margin:0 auto;background:#fff;border-radius:12px;box-shadow:0 10px 40px rgba(0,0,0,.08);overflow:hidden}
.header{padding:28px;background:linear-gradient(90deg,#5562f7,#8b5cf6);color:#fff;text-align:center}
.header h1{margin:0;font-size:1.8rem}
#content{padding:28px;min-height:360px}
button{background:#5562f7;color:#fff;border:none;padding:10px 18px;border-radius:8px;cursor:pointer}
.btn-ghost{background:#eef2ff;color:#111}
.quiz-option{display:block;width:100%;text-align:left;padding:12px;border-radius:8px;margin:8px 0;border:1px solid #eef2ff;background:#fbfdff}
pre.code{background:#0f1724;color:#a7f3d0;padding:12px;border-radius:8px;overflow:auto}
.hint{background:#fff7ed;border-left:4px solid #f59e0b;padding:12px;border-radius:6px;margin:12px 0}
.feedback{padding:14px;border-radius:8px;margin:12px 0}
.feedback.success{background:#ecfdf5;border-left:4px solid #10b981;}
.feedback.error{background:#fff1f2;border-left:4px solid #ef4444;}
footer{padding:16px;text-align:center;font-size:.9rem;color:#6b7280;}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Learn HTML — Interactive Mini Tutorial</h1>
<p style="opacity:.9;margin-top:6px">Hands-on lessons, short quizzes and tiny exercises.</p>
</div>
<div id="content" data-signals='{"progress":0,"mastery":0}'>
{{template "intro" .}}
</div>
<footer>
Progress: <span data-signal="progress">0</span>% &nbsp;&nbsp; Mastery: <span data-signal="mastery">0</span>%
</footer>
</div>
</body>
</html>
{{end}}
{{/* --- Intro screen --- */}}
{{define "intro"}}
<div style="padding:8px 0 0 0">
<div style="margin-bottom:18px">
<h2>Welcome 👋</h2>
<p>In this short interactive tutorial you'll learn what HTML is, try a quick quiz, and write your first &lt;h1&gt; tag.</p>
</div>
<div style="display:flex;gap:12px;align-items:center">
<button data-on:click="@get('/node/what-is-html')">Start Learning</button>
<button class="btn-ghost" data-on:click="@get('/node/summary')">See Outline</button>
</div>
</div>
{{end}}
{{/* --- Outline / summary --- */}}
{{define "summary"}}
<h2>Lesson Outline</h2>
<ul>
<li>What is HTML? (short)</li>
<li>Quiz: basic concept</li>
<li>Exercise: create a heading (&lt;h1&gt;)</li>
</ul>
<p>
<button data-on:click="@get('/node/what-is-html')">Begin Lesson</button>
</p>
{{end}}
{{/* --- Short lesson node --- */}}
{{define "what-is-html"}}
<h2>What is HTML?</h2>
<p><strong>HTML</strong> stands for <em>HyperText Markup Language</em>. It's the language used to describe the structure of web pages using tags such as &lt;h1&gt;, &lt;p&gt;, &lt;a&gt; and others.</p>
<h3>Key ideas</h3>
<ul>
<li>HTML is markup, not a programming language.</li>
<li>Elements use tags: &lt;tag&gt;content&lt;/tag&gt;.</li>
<li>Browsers render HTML to show pages.</li>
</ul>
<div style="margin-top:18px">
<button data-on:click="@get('/node/quiz-what-is-html')">Take a quick quiz</button>
<button class="btn-ghost" data-on:click="@get('/node/exercise-first-tag')">Try an exercise instead</button>
</div>
{{end}}
{{/* --- Quiz node --- */}}
{{define "quiz-what-is-html"}}
<h2>Quiz — What is HTML?</h2>
<p>Choose the best answer:</p>
<div style="margin-top:12px">
{{range .QuizOptions}}
<button class="quiz-option" data-on:click="@post('/answer', {quiz: 'quiz-what-is-html', answer: '{{.ID}}'})">
<strong>{{.ID | printf "%s."}}</strong> {{.Text}}
</button>
{{end}}
</div>
<div id="quiz-feedback" style="margin-top:12px"></div>
<div style="margin-top:16px">
<button class="btn-ghost" data-on:click="@get('/node/what-is-html')">Back</button>
</div>
{{end}}
{{/* Keep an alias if older links use the other name */}}
{{define "quiz-html-tags"}}{{template "quiz-what-is-html" .}}{{end}}
{{/* --- Exercise: first tag --- */}}
{{define "exercise-first-tag"}}
<h2>Exercise — Your first &lt;h1&gt;</h2>
<p>Finish the HTML snippet so the page shows a heading that reads <strong>Hello World</strong>.</p>
<pre class="code">&lt;!doctype html&gt;
&lt;html&gt;
&lt;body&gt;
<!-- add a heading below -->
{{printf "%s" ""}}
&lt;/body&gt;
&lt;/html&gt;</pre>
<textarea id="code" placeholder="Type your HTML here">&lt;h1&gt;Hello World&lt;/h1&gt;</textarea>
<div style="margin-top:12px">
<button data-on:click="$$post('/code/check', {exerciseId: 'first-tag', code: document.querySelector('#code').value})">Run & Check</button>
<button class="btn-ghost" data-on:click="@get('/node/what-is-html')">Skip</button>
</div>
<div id="exercise-feedback" style="margin-top:12px"></div>
{{end}}
{{/* --- Feedback fragments --- */}}
{{define "correct-answer"}}
<div class="feedback success">
<h3>✅ Correct</h3>
<p>{{.Explanation}}</p>
<button data-on:click="@get('/node/{{.NextNode}}')">Continue</button>
</div>
{{end}}
{{define "wrong-answer"}}
<div class="feedback error">
<h3>❌ Not quite</h3>
{{if .ShowHint}}<div class="hint">{{.Hint}}</div>{{end}}
<p>Try again or review the lesson.</p>
<div style="margin-top:10px">
<button data-on:click="@get('/node/quiz-what-is-html')">Try Again</button>
<button class="btn-ghost" data-on:click="@get('/node/what-is-html')">Review</button>
</div>
</div>
{{end}}
{{/* --- Code-check results --- */}}
{{define "code-pass"}}
<div class="feedback success">
<h3>🎉 Nice work — it passed!</h3>
<p>{{.Output}}</p>
<button data-on:click="@get('/node/quiz-what-is-html')">Go to Quiz</button>
</div>
{{end}}
{{define "code-fail"}}
<div class="feedback error">
<h3>Looks like there is an issue</h3>
<p>{{.Error}}</p>
<button class="btn-ghost" data-on:click="@get('/node/exercise-first-tag')">Open Editor</button>
</div>
{{end}}