feat(help): add interactive student tutorial with video and integrated help page

- Create student tutorial documentation in Markdown with updated asset paths
 - Add backend routes to serve rendered help content and assets via JSON API
 - Implement frontend /help route using SvelteKit for professional rendering
 - Add "Bantuan" link to the navigation bar with custom styling
 - Generate tutorial screenshots and a demo video with virtual cursor and subtitles
 - Configure Tailscale and Vite proxies to support the new help routing
 - Add automated video generation scripts and assets
master
a2nr 2026-04-20 13:43:45 +07:00
parent 89f0967c3e
commit 6d5c27f93f
17 changed files with 201 additions and 2 deletions

2
app.py
View File

@ -32,11 +32,13 @@ def create_app():
from routes.compile import compile_bp from routes.compile import compile_bp
from routes.lessons import lessons_bp from routes.lessons import lessons_bp
from routes.progress import progress_bp from routes.progress import progress_bp
from routes.help import help_bp
app.register_blueprint(auth_bp) app.register_blueprint(auth_bp)
app.register_blueprint(compile_bp) app.register_blueprint(compile_bp)
app.register_blueprint(lessons_bp) app.register_blueprint(lessons_bp)
app.register_blueprint(progress_bp) app.register_blueprint(progress_bp)
app.register_blueprint(help_bp)
# ── Startup tasks ───────────────────────────────────────────────── # ── Startup tasks ─────────────────────────────────────────────────
initialize_tokens_file(get_lesson_names()) initialize_tokens_file(get_lesson_names())

View File

@ -60,6 +60,10 @@
{$themeDark ? '\u2600\uFE0F' : '\uD83C\uDF19'} {$themeDark ? '\u2600\uFE0F' : '\uD83C\uDF19'}
</button> </button>
<a href="/help" target="_blank" class="nav-help-link" title="Panduan Penggunaan">
Bantuan
</a>
{#if $authLoggedIn} {#if $authLoggedIn}
<span class="user-label">{$authStudentName}</span> <span class="user-label">{$authStudentName}</span>
<button class="btn btn-danger btn-xs" onclick={() => auth.logout()}>Keluar</button> <button class="btn btn-danger btn-xs" onclick={() => auth.logout()}>Keluar</button>
@ -202,6 +206,21 @@
padding: 0.25rem 0.6rem; padding: 0.25rem 0.6rem;
font-size: 0.75rem; font-size: 0.75rem;
} }
.nav-help-link {
color: #fff;
text-decoration: none;
font-size: 0.75rem;
font-weight: 600;
padding: 0.25rem 0.6rem;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 6px;
transition: background 0.15s;
}
.nav-help-link:hover {
background: rgba(255, 255, 255, 0.15);
color: #fff;
text-decoration: none;
}
/* ── Modal ──────────────────────────────────────── */ /* ── Modal ──────────────────────────────────────── */
.modal-overlay { .modal-overlay {

View File

@ -0,0 +1,49 @@
<script lang="ts">
let { data } = $props();
</script>
<svelte:head>
<title>{data.help.title} - Elemes LMS</title>
</svelte:head>
<div class="help-container">
<header class="help-header">
<h1>{data.help.title}</h1>
</header>
<section class="help-content prose">
{@html data.help.content}
</section>
</div>
<style>
.help-container {
max-width: 900px;
margin: 0 auto;
padding: 2rem 1rem;
}
.help-header {
margin-bottom: 2rem;
border-bottom: 2px solid var(--color-border);
padding-bottom: 1rem;
}
.help-header h1 {
font-size: 2.5rem;
margin: 0;
}
.help-content {
background: var(--color-bg-secondary);
padding: 2rem;
border-radius: var(--radius);
box-shadow: var(--shadow);
}
@media (max-width: 768px) {
.help-header h1 {
font-size: 1.75rem;
}
.help-content {
padding: 1rem;
}
}
</style>

View File

@ -0,0 +1,12 @@
import { error } from '@sveltejs/kit';
export async function load({ fetch }) {
const res = await fetch('/api/help');
if (!res.ok) {
throw error(res.status, 'Gagal memuat panduan');
}
const data = await res.json();
return {
help: data
};
}

87
help/TUTORIAL_SISWA.md Normal file
View File

@ -0,0 +1,87 @@
# Panduan Penggunaan LMS Elemes (Sinau-C)
Selamat datang di LMS Elemes! Panduan ini akan membantu kamu memahami cara menggunakan platform ini untuk belajar pemrograman C, elektronika, dan Arduino secara interaktif.
---
## 1. Memasukkan Token
Untuk mulai belajar, kamu perlu masuk menggunakan token yang diberikan oleh gurumu.
- Buka halaman utama LMS
- Klik tombol **"Masuk"** di pojok kanan atas.
- Masukkan token kamu (contoh: `dummy_token_12345`) dan klik **"Masuk"**.
![Memasukkan Token](/api/help/asset/tutorial_2_token.png)
---
## 2. Navigasi ke Kursus
Setelah berhasil masuk, nama kamu akan muncul di pojok kanan atas. Kamu bisa melihat daftar materi yang tersedia di halaman Home.
- Klik pada **Kartu Materi** (misalnya: "Hello, World!") untuk masuk ke halaman pelajaran.
![Dashboard Siswa](/api/help/asset/tutorial_9_progress.png)
---
## 3. Pengoperasian Halaman Lesson (Mode Desktop)
Halaman pelajaran terbagi menjadi dua bagian utama: **Materi** di sisi kiri dan **Workspace** di sisi kanan.
### Tab Workspace
Workspace memiliki beberapa tab sesuai dengan materi yang sedang dipelajari:
- **Info**: Menampilkan tujuan pembelajaran dan prasyarat.
- **Exercise**: Instruksi tugas yang harus diselesaikan.
- **C / Python**: Editor kode untuk menulis program.
- **Circuit / Arduino**: Simulator rangkaian atau mikrokontroler.
- **Output**: Hasil eksekusi program kamu.
![Halaman Pelajaran](/api/help/asset/tutorial_4_lesson_desktop.png)
### Floating & Docked Mode
Kamu bisa merubah tampilan Workspace agar lebih fleksibel:
- **Floating Mode**: Klik ikon kotak bertumpuk (**⊞**) di pojok kanan atas Workspace untuk menjadikannya jendela melayang.
- **Docker Workspace**: Klik ikon panah bawah (**▽**) untuk meminimalkan Workspace, atau klik ikon kotak (**⊡**) untuk mengembalikannya ke posisi semula (docked).
- **Resize**: Tarik ikon di pojok kiri atas jendela melayang (**◳**) untuk mengubah ukuran Workspace.
![Workspace Floating](/api/help/asset/tutorial_5_floating_workspace.png)
---
## 4. Pemrograman C dan Python
Di tab **C** atau **Python**, kamu bisa langsung menulis kode.
- Klik tombol **"▶ Run"** untuk menjalankan kodemu.
- Hasilnya akan muncul di tab **Output**.
- Gunakan tombol **"Reset"** jika ingin mengulang kode ke kondisi awal.
![Workspace C](/api/help/asset/tutorial_6_c_workspace.png)
---
## 5. Simulasi CircuitJS
Untuk materi elektronika, kamu bisa menggunakan simulator **CircuitJS**.
- Pilih tab **"Circuit"**.
- Kamu bisa melihat simulasi aliran arus secara *real-time*.
- Kamu bisa berinteraksi dengan komponen (seperti saklar) langsung di dalam simulator.
![Simulator CircuitJS](/api/help/asset/tutorial_7_circuitjs_workspace.png)
---
## 6. Simulasi Velxio (Arduino)
Untuk materi Arduino, platform ini menyediakan simulator **Velxio**.
- Pilih tab **"Arduino"**.
- Tulis kode `.ino` kamu di sisi kiri editor.
- Klik tombol **"Run"** (ikon petir/play) untuk mengunggah kode ke Arduino virtual.
- Perhatikan komponen di sisi kanan (seperti LED) yang akan bereaksi sesuai kodemu.
![Simulator Velxio](/api/help/asset/tutorial_8_velxio_workspace.png)
---
## 7. Memantau Keberhasilan Exercise
Platform ini akan otomatis mendeteksi jika kamu telah berhasil menyelesaikan tugas.
- Jika tugas selesai, akan muncul tanda centang hijau (**✓ Selesai**) di samping judul materi.
- Kamu juga bisa melihat status penyelesaian di halaman Home (Dashboard) pada setiap kartu materi.
![Status Selesai](/api/help/asset/tutorial_9_progress.png)
---
*Selamat belajar dan selamat bereksperimen!*

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

View File

@ -20,8 +20,8 @@ services:
elemes-frontend: elemes-frontend:
build: ./frontend build: ./frontend
image: lms-c-frontend:latest image: lms-c-frontend:latest
ports: # ports:
- 3000:3000 # - 3000:3000
environment: environment:
- ORIGIN=http://localhost:3000 - ORIGIN=http://localhost:3000
- API_BACKEND=http://elemes:5000 - API_BACKEND=http://elemes:5000
@ -77,3 +77,4 @@ volumes:
networks: networks:
main_network: main_network:
driver: bridge driver: bridge
network_mode: service:elemes-ts

29
routes/help.py Normal file
View File

@ -0,0 +1,29 @@
import os
import markdown as md
from flask import Blueprint, jsonify, send_from_directory
from services.lesson_service import MD_EXTENSIONS
help_bp = Blueprint('help_api', __name__)
HELP_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'help')
@help_bp.route('/help')
def get_help_content():
file_path = os.path.join(HELP_DIR, 'TUTORIAL_SISWA.md')
if not os.path.exists(file_path):
return jsonify({'error': 'Help content not found'}), 404
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Render markdown to HTML
html_content = md.markdown(content, extensions=MD_EXTENSIONS)
return jsonify({
'title': 'Panduan Penggunaan',
'content': html_content
})
@help_bp.route('/help/asset/<path:filename>')
def serve_help_asset(filename):
return send_from_directory(os.path.join(HELP_DIR, 'asset'), filename)