Files
geograsim/App/login.html
T
Adminator b06aa025c1 Login-Frontend + Lehrer-Dashboard + Stadt-Simulation komplett
- login.html: Schueler-Login (Klassencode+User+PW) + Lehrer-Login/Register
- teacher.html: Vollstaendiges Dashboard (Klassen, Schueler, Module, Stats)
- stadt.html: Komplette Simulation mit 27 Kachel-Typen + Kennwerten
- tile-test.html: Spital-Sackgassen gefixt
- PHP-Pages fuer alle neuen HTML-Seiten

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 08:37:08 +02:00

176 lines
7.7 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GeoGraSim — Anmelden</title>
<link rel="icon" type="image/png" href="assets/img/logo.png">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Inter',sans-serif;background:#f7f6f3;min-height:100vh;display:flex;align-items:center;justify-content:center}
.card{background:#fff;border-radius:16px;padding:2rem;max-width:400px;width:90%;box-shadow:0 8px 30px rgba(0,0,0,.08)}
.logo{text-align:center;margin-bottom:1.2rem}
.logo h1{font-size:1.3rem;font-weight:800;color:#4a7c8a;letter-spacing:-.02em}
.logo p{font-size:.78rem;color:#8a8a8a;margin-top:.2rem}
.tabs{display:flex;gap:0;margin-bottom:1.2rem;border-radius:8px;overflow:hidden;border:1px solid rgba(0,0,0,.08)}
.tab{flex:1;padding:.5rem;text-align:center;font-size:.75rem;font-weight:600;cursor:pointer;background:#f7f6f3;color:#8a8a8a;transition:all .15s}
.tab.on{background:#4a7c8a;color:#fff}
label{display:block;font-size:.72rem;font-weight:600;color:#4a4a4a;margin-bottom:.2rem;margin-top:.8rem}
input{width:100%;padding:.55rem .7rem;border:1.5px solid rgba(0,0,0,.1);border-radius:7px;font-size:.82rem;font-family:inherit;outline:none;transition:border .15s}
input:focus{border-color:#4a7c8a}
.btn{width:100%;padding:.6rem;border:none;border-radius:8px;background:#4a7c8a;color:#fff;font-size:.85rem;font-weight:700;cursor:pointer;margin-top:1rem;transition:background .15s}
.btn:hover{background:#3a6470}
.btn-secondary{background:transparent;color:#4a7c8a;border:1.5px solid #4a7c8a}
.btn-secondary:hover{background:#dae8ec}
.msg{margin-top:.8rem;font-size:.75rem;padding:.4rem .6rem;border-radius:6px;display:none}
.msg.err{display:block;background:#f2ddd8;color:#c07a6b}
.msg.ok{display:block;background:#dceadd;color:#5a8a5e}
.link{text-align:center;margin-top:.8rem;font-size:.72rem;color:#8a8a8a}
.link a{color:#4a7c8a;text-decoration:none;font-weight:600}
.hidden{display:none}
</style>
</head>
<body>
<div class="card">
<div class="logo">
<h1>🌍 GeoGraSim</h1>
<p>Interaktive Simulationen für den Geografieunterricht</p>
</div>
<div class="tabs">
<div class="tab on" data-tab="student">Schüler:in</div>
<div class="tab" data-tab="teacher">Lehrkraft</div>
</div>
<!-- SCHUELER LOGIN -->
<form id="f-student">
<label>Klassencode</label>
<input type="text" id="s-code" placeholder="z.B. GEO1A" maxlength="6" autocapitalize="characters">
<label>Benutzername</label>
<input type="text" id="s-user" placeholder="z.B. schueler01">
<label>Passwort</label>
<input type="password" id="s-pass">
<button type="submit" class="btn">Anmelden</button>
</form>
<!-- LEHRER LOGIN -->
<form id="f-teacher" class="hidden">
<div id="teacher-login">
<label>E-Mail</label>
<input type="email" id="t-email" placeholder="name@schule.at">
<label>Passwort</label>
<input type="password" id="t-pass">
<button type="submit" class="btn">Anmelden</button>
<div class="link"><a href="#" id="show-register">Noch kein Konto? Jetzt registrieren</a></div>
</div>
<div id="teacher-register" class="hidden">
<label>Name</label>
<input type="text" id="r-name" placeholder="Vor- und Nachname">
<label>Schule</label>
<input type="text" id="r-school" placeholder="Name der Schule">
<label>E-Mail</label>
<input type="email" id="r-email" placeholder="name@schule.at">
<label>Passwort (mind. 8 Zeichen)</label>
<input type="password" id="r-pass" minlength="8">
<label>Passwort bestätigen</label>
<input type="password" id="r-pass2">
<button type="submit" class="btn">Registrieren</button>
<div class="link"><a href="#" id="show-login">Bereits registriert? Anmelden</a></div>
</div>
</form>
<div class="msg" id="msg"></div>
</div>
<script>
var BASE = (window.__GGS__?.baseUrl) || ''
var tabs = document.querySelectorAll('.tab')
var fStudent = document.getElementById('f-student')
var fTeacher = document.getElementById('f-teacher')
var msg = document.getElementById('msg')
var isRegister = false
tabs.forEach(function(t) {
t.addEventListener('click', function() {
tabs.forEach(function(x){x.className='tab'})
this.className='tab on'
fStudent.classList.toggle('hidden', this.dataset.tab !== 'student')
fTeacher.classList.toggle('hidden', this.dataset.tab !== 'teacher')
msg.className = 'msg'
})
})
document.getElementById('show-register').addEventListener('click', function(e) {
e.preventDefault(); isRegister = true
document.getElementById('teacher-login').classList.add('hidden')
document.getElementById('teacher-register').classList.remove('hidden')
})
document.getElementById('show-login').addEventListener('click', function(e) {
e.preventDefault(); isRegister = false
document.getElementById('teacher-login').classList.remove('hidden')
document.getElementById('teacher-register').classList.add('hidden')
})
function showMsg(text, type) {
msg.textContent = text
msg.className = 'msg ' + type
}
async function api(action, data) {
var res = await fetch(BASE + '/api/auth', {
method: 'POST', headers: {'Content-Type':'application/json'}, credentials:'same-origin',
body: JSON.stringify(Object.assign({action: action}, data))
})
return await res.json()
}
// Schueler-Login
fStudent.addEventListener('submit', async function(e) {
e.preventDefault()
var code = document.getElementById('s-code').value.trim().toUpperCase()
var user = document.getElementById('s-user').value.trim()
var pass = document.getElementById('s-pass').value
if (!code || !user || !pass) { showMsg('Alle Felder ausfüllen!', 'err'); return }
var r = await api('student_login', {classCode: code, username: user, password: pass})
if (r.error) { showMsg(r.error, 'err'); return }
showMsg('Willkommen, ' + r.displayName + '!', 'ok')
setTimeout(function() { location.href = 'index.html' }, 800)
})
// Lehrer-Login/Register
fTeacher.addEventListener('submit', async function(e) {
e.preventDefault()
if (isRegister) {
var name = document.getElementById('r-name').value.trim()
var school = document.getElementById('r-school').value.trim()
var email = document.getElementById('r-email').value.trim()
var pass = document.getElementById('r-pass').value
var pass2 = document.getElementById('r-pass2').value
if (!name || !email || !pass) { showMsg('Alle Felder ausfüllen!', 'err'); return }
if (pass !== pass2) { showMsg('Passwörter stimmen nicht überein!', 'err'); return }
if (pass.length < 8) { showMsg('Passwort muss mindestens 8 Zeichen haben!', 'err'); return }
var r = await api('register', {displayName: name, schoolName: school, email: email, password: pass})
if (r.error) { showMsg(r.error, 'err'); return }
showMsg('Registrierung erfolgreich!', 'ok')
setTimeout(function() { location.href = 'teacher.html' }, 800)
} else {
var email = document.getElementById('t-email').value.trim()
var pass = document.getElementById('t-pass').value
if (!email || !pass) { showMsg('E-Mail und Passwort ausfüllen!', 'err'); return }
var r = await api('login', {email: email, password: pass})
if (r.error) { showMsg(r.error, 'err'); return }
showMsg('Willkommen, ' + r.displayName + '!', 'ok')
setTimeout(function() { location.href = 'teacher.html' }, 800)
}
})
// Check ob schon eingeloggt
api('status', {}).then(function(r) {
if (r.role === 'teacher') location.href = 'teacher.html'
if (r.role === 'student') location.href = 'index.html'
})
</script>
</body>
</html>