g3.6
This commit is contained in:
1 parent
bdeaece35a
commit
16bc5ea38e
11 files changed
+445
-338
No files matched your search
+26
@@ -0,0 +1,26 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<script src="./auth.js"></script>
|
||||
<script src="./lib/basic.js"></script>
|
||||
<script src="./help/data_xample.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
await createTemp();
|
||||
location.href = "./login.html";
|
||||
} catch(err) {
|
||||
alert("Ein Fehler ist aufgetreten: " + err);
|
||||
}
|
||||
})();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+28
-19
@@ -3,12 +3,11 @@ async function createTemp() {
|
||||
await couchDB.set("users", {
|
||||
"turtle": {
|
||||
"password": "1234",
|
||||
"level": 1,
|
||||
"level": 0,
|
||||
"xp": 0,
|
||||
"avatar": null,
|
||||
"abilities": [
|
||||
],
|
||||
"enabled_abilities": [
|
||||
],
|
||||
"abilities": [],
|
||||
"enabled_abilities": [],
|
||||
"role": "student",
|
||||
"courses": [
|
||||
"weiche_ware",
|
||||
@@ -17,8 +16,9 @@ async function createTemp() {
|
||||
},
|
||||
"dumble-door": {
|
||||
"password": "bla",
|
||||
"level": 4,
|
||||
"avatar": "https://static.turtle-coding-gbr.de/profile-pic.png",
|
||||
"level": 10,
|
||||
"xp": 0,
|
||||
"avatar": "https://static.turtle-coding-gbr.de/gmci/profile-pic.png",
|
||||
"abilities": [
|
||||
],
|
||||
"enabled_abilities": [
|
||||
@@ -30,9 +30,18 @@ async function createTemp() {
|
||||
},
|
||||
"narrator": {
|
||||
"password": "stanley",
|
||||
"level": 4,
|
||||
"avatar": "https://static.turtle-coding-gbr.de/st",
|
||||
"level": 10,
|
||||
"xp": 0,
|
||||
"avatar": "https://static.turtle-coding-gbr.de/gmci/st",
|
||||
"abilities": [
|
||||
"dark_mode",
|
||||
"accent_color",
|
||||
"pink_mode",
|
||||
"profile_pic",
|
||||
"simple_border",
|
||||
"gold_border",
|
||||
"epic_border",
|
||||
"title_of_honor"
|
||||
],
|
||||
"enabled_abilities": [
|
||||
],
|
||||
@@ -72,17 +81,17 @@ async function createTemp() {
|
||||
{
|
||||
"date": "2025-12-27",
|
||||
"questions": [
|
||||
{ "title": "1", "type": "text" },
|
||||
{ "title": "2", "type": "scala" }
|
||||
{ "title": "Wie war die Vorlesung?", "type": "text" },
|
||||
{ "title": "Wie war der Professor?", "type": "scala" }
|
||||
],
|
||||
"result": [
|
||||
["Gut, aber ...", 5],
|
||||
["Schlecht", 1]
|
||||
["Gut, weil ...", 5],
|
||||
["Schlecht, weil ...", 1]
|
||||
]
|
||||
}
|
||||
],
|
||||
"start_date": "2025-12-23",
|
||||
"expire_date": "2025-12-27"
|
||||
"expire_date": "2026-02-20"
|
||||
});
|
||||
await couchDB.set("course:weiche_ware", {
|
||||
"title": "Weiche Ware",
|
||||
@@ -99,8 +108,8 @@ async function createTemp() {
|
||||
}
|
||||
],
|
||||
"result": [
|
||||
["Gut, aber ...", 5],
|
||||
["Schlecht", 1]
|
||||
["Gut, weil ...", 5],
|
||||
["Schlecht, weil ...", 1]
|
||||
],
|
||||
"result_history": [
|
||||
{
|
||||
@@ -110,12 +119,12 @@ async function createTemp() {
|
||||
{ "title": "2", "type": "scala" }
|
||||
],
|
||||
"result": [
|
||||
["Gut, aber ...", 5],
|
||||
["Schlecht", 1]
|
||||
["Gut, weil ...", 5],
|
||||
["Schlecht, weil ...", 1]
|
||||
]
|
||||
}
|
||||
],
|
||||
"start_date": "2025-12-23",
|
||||
"expire_date": "2025-12-27"
|
||||
"expire_date": "2025-02-20"
|
||||
});
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 9.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 9.3 KiB |
+64
-8
@@ -374,14 +374,15 @@ var userData = null;
|
||||
const userDataListener = [];
|
||||
|
||||
async function setUserData(couchDB) {
|
||||
const res = await getUserData(couchDB);
|
||||
if (res == null) {
|
||||
const user = await getUserData(couchDB);
|
||||
if (user == null) {
|
||||
location.href = "../login.html";
|
||||
return false;
|
||||
}
|
||||
userData = res;
|
||||
updateAllProfiles(res);
|
||||
_constructProfile(res);
|
||||
userData = user;
|
||||
updateAllProfiles(user);
|
||||
_constructProfile(user);
|
||||
await checkUserCourses(couchDB, user);
|
||||
|
||||
while (userDataListener.length > 0) {
|
||||
const call = userDataListener[userDataListener.length - 1];
|
||||
@@ -407,18 +408,51 @@ async function updateUserData(couchDB, user = userData) {
|
||||
|
||||
|
||||
function updateAllProfiles(user) {
|
||||
const hasProfilAbility = user.enabled_abilities.includes("profile_pic");
|
||||
const features = user.enabled_abilities ??= [];
|
||||
const hasProfilAbility = features.includes("profile_pic");
|
||||
|
||||
const profiles = document.getElementsByClassName("profile");
|
||||
for (var i of profiles) {
|
||||
if (hasProfilAbility) {
|
||||
if (hasProfilAbility && user.avatar) {
|
||||
i.style.backgroundImage = `url("${user.avatar}")`;
|
||||
} else {
|
||||
i.style.removeProperty("backgroundImage");
|
||||
if (features.includes("pink_mode")) {
|
||||
i.style.backgroundImage = `url("https://static.turtle-coding-gbr.de/gmci/rosa_profil.png")`;
|
||||
} else {
|
||||
i.style.backgroundImage = `url("https://static.turtle-coding-gbr.de/gmci/standart_profil.png")`;
|
||||
}
|
||||
}
|
||||
i.onclick = _onProfileClick;
|
||||
}
|
||||
}
|
||||
async function checkUserCourses(couchDB, userData) {
|
||||
for (var cName of userData.courses) {
|
||||
const course = await couchDB.get("course:" + cName);
|
||||
if (!course || !course.expire_date) continue;
|
||||
|
||||
const expire_date = new Date(course.expire_date);
|
||||
if (expire_date < new Date()) {
|
||||
course.result_history ??= [];
|
||||
course.questions ??= [];
|
||||
course.result ??= [];
|
||||
|
||||
if (course.questions.length == 0 || course.result.length == 0) continue;
|
||||
|
||||
course.result_history.push({
|
||||
"date": course.start_date ?? expire_date,
|
||||
"questions": course.questions,
|
||||
"result": course.result
|
||||
});
|
||||
course.questions = [];
|
||||
course.result = [];
|
||||
|
||||
await couchDB.set("course:" + cName, course);
|
||||
|
||||
console.log(`Course ${cName} expired`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _onProfileClick(event) {
|
||||
var buttonRect = this.getBoundingClientRect();
|
||||
|
||||
@@ -542,4 +576,26 @@ function getUserDisplayName(user) {
|
||||
const hasHonor = (user.enabled_abilities ??= []).includes("title_of_honor");
|
||||
const title_of_honor = hasHonor ? "(Sir) " : "";
|
||||
return `${title_of_honor}${ !user.title ? "" : user.title + " " }${ form1(user.name) }`;
|
||||
}
|
||||
|
||||
async function levelUpXP(couchDB, user = userData, xp = 1) {
|
||||
var resLevelUp = false;
|
||||
|
||||
userData.xp ??= 0;
|
||||
userData.level ??= 0;
|
||||
|
||||
userData.xp += xp;
|
||||
while (userData.xp >= userData.level+1) {
|
||||
userData.xp -= (userData.level + 1);
|
||||
userData.level++;
|
||||
resLevelUp = true;
|
||||
}
|
||||
|
||||
if (userData.xp < 0) {
|
||||
console.error("UserData-XP was below zero!");
|
||||
userData.xp = 0;
|
||||
}
|
||||
|
||||
await updateUserData(couchDB, user);
|
||||
return resLevelUp;
|
||||
}
|
||||
+135
-141
@@ -1,160 +1,154 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Login</title>
|
||||
<link rel="stylesheet" href="./lib/basic.css" />
|
||||
<script src="./auth.js" defer></script>
|
||||
<script src="./lib/basic.js" defer></script>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Login</title>
|
||||
<link rel="stylesheet" href="./lib/basic.css" />
|
||||
<script src="./auth.js"></script>
|
||||
<script src="./lib/basic.js"></script>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
background-color: #fff;
|
||||
padding: 2.5rem 2rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
}
|
||||
.login-card {
|
||||
background-color: #fff;
|
||||
padding: 2.5rem 2rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.login-card h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.login-card h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 0.3rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 0.3rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 0.5rem 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid #d1d5da;
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 0.5rem 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid #d1d5da;
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 0.6rem;
|
||||
background-color: #2ea44f;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 0.6rem;
|
||||
background-color: var(--accent_color_fg);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #279f43;
|
||||
}
|
||||
button:hover {
|
||||
background-color: var(--accent_color_fg_o);
|
||||
}
|
||||
|
||||
.signup-text {
|
||||
text-align: center;
|
||||
margin-top: 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.signup-text {
|
||||
text-align: center;
|
||||
margin-top: 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.signup-text a {
|
||||
color: #0366d6;
|
||||
text-decoration: none;
|
||||
}
|
||||
.signup-text a {
|
||||
color: #0366d6;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.signup-text a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-card">
|
||||
<h1>Sign in</h1>
|
||||
.signup-text a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-card">
|
||||
<h1>Sign in</h1>
|
||||
|
||||
<label for="username">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
autocomplete="username"
|
||||
autocapitalize="off"
|
||||
autocorrect="off"
|
||||
required
|
||||
autofocus
|
||||
/>
|
||||
<label for="username">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
autocomplete="username"
|
||||
autocapitalize="off"
|
||||
autocorrect="off"
|
||||
required
|
||||
autofocus
|
||||
/>
|
||||
|
||||
<label for="password">Password</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
autocomplete="current-password"
|
||||
required
|
||||
/>
|
||||
<label for="password">Password</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
autocomplete="current-password"
|
||||
required
|
||||
/>
|
||||
|
||||
<button type="button" onclick="login()">Sign in</button>
|
||||
<button type="button" onclick="login()">Sign in</button>
|
||||
|
||||
<div class="signup-text">
|
||||
Don't have an account yet? <a href="signup.html">Sign up</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="signup-text">Don't have an account yet? <a href="signup.html">Sign up</a></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const couchDB = new CouchDB();
|
||||
<script>
|
||||
const couchDB = new CouchDB();
|
||||
|
||||
async function getData() {
|
||||
try {
|
||||
const res = await couchDB.get("users");
|
||||
return res || {};
|
||||
} catch (e) {
|
||||
console.error("Failed to get users:", e);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
async function getData() {
|
||||
try {
|
||||
const res = await couchDB.get("users");
|
||||
return res ?? {};
|
||||
} catch (e) {
|
||||
console.error("Failed to get users:", e);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
async function login() {
|
||||
const data = await getData();
|
||||
const username = document
|
||||
.getElementById("username")
|
||||
.value.trim()
|
||||
.toLowerCase();
|
||||
const password = document.getElementById("password").value;
|
||||
async function login() {
|
||||
const data = await getData();
|
||||
const username = document.getElementById("username").value.trim().toLowerCase();
|
||||
const password = document.getElementById("password").value;
|
||||
|
||||
const user = data[username];
|
||||
if (user == undefined) {
|
||||
return alert("User doesn't exist!");
|
||||
}
|
||||
if (user.password != password) {
|
||||
return alert("Incorrect password!");
|
||||
}
|
||||
if (user.role === "student") {
|
||||
location.href =
|
||||
"./student/uebersicht.html?user=" + username;
|
||||
return;
|
||||
} else {
|
||||
location.href = "./prof/uebersicht.html?user=" + username;
|
||||
return;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
const user = data[username];
|
||||
if (user == undefined) {
|
||||
return alert("User doesn't exist!");
|
||||
}
|
||||
if (user.password != password) {
|
||||
return alert("Incorrect password!");
|
||||
}
|
||||
if (user.role === "student") {
|
||||
location.href = "./student/uebersicht.html?user=" + username;
|
||||
return;
|
||||
} else {
|
||||
location.href = "./prof/uebersicht.html?user=" + username;
|
||||
return;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+7
-2
@@ -108,9 +108,14 @@ const _skillCb = {
|
||||
},
|
||||
"unset_epic_border": () => unsetProfileBorder(),
|
||||
"title_of_honor": function() {},
|
||||
"profile_pic": () => updateAllProfiles(userData)
|
||||
"profile_pic": () => updateEverything()
|
||||
};
|
||||
|
||||
function updateEverything() {
|
||||
updateAllProfiles(userData);
|
||||
refreshOverlays();
|
||||
}
|
||||
|
||||
function chooseAccentColor() {
|
||||
var elm = getId("skill_chooseAccentColor");
|
||||
if (!elm) {
|
||||
@@ -142,7 +147,7 @@ function setAccentColor(elm) {
|
||||
|
||||
hideOverlay("skill_chooseAccentColor");
|
||||
_skillCb.accent_color();
|
||||
refreshOverlays();
|
||||
updateEverything()
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ async function activateSkill(elm, data) {
|
||||
try { eval(data.call_unset); } catch (err) { console.error(err); }
|
||||
}
|
||||
}
|
||||
refreshOverlays();
|
||||
updateEverything();
|
||||
}
|
||||
async function _buySkill(data) {
|
||||
const elms = document.getElementsByClassName("skill_" + data.id);
|
||||
|
||||
+160
-164
@@ -1,189 +1,185 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Sign Up</title>
|
||||
<link rel="stylesheet" href="./lib/basic.css" />
|
||||
<script src="./auth.js" defer></script>
|
||||
<script src="./lib/basic.js" defer></script>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Sign Up</title>
|
||||
<link rel="stylesheet" href="./lib/basic.css" />
|
||||
<script src="./auth.js"></script>
|
||||
<script src="./lib/basic.js"></script>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background-color: #f6f8fa;
|
||||
padding: 2rem 0;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background-color: #f6f8fa;
|
||||
padding: 2rem 0;
|
||||
}
|
||||
|
||||
.signup-card {
|
||||
background-color: #fff;
|
||||
padding: 2.5rem 2rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
}
|
||||
.signup-card {
|
||||
background-color: #fff;
|
||||
padding: 2.5rem 2rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.signup-card h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.signup-card h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 0.3rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 0.3rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
input,
|
||||
select {
|
||||
width: 100%;
|
||||
padding: 0.5rem 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid #d1d5da;
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
input,
|
||||
select {
|
||||
width: 100%;
|
||||
padding: 0.5rem 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid #d1d5da;
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 0.6rem;
|
||||
background-color: #2ea44f;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 0.6rem;
|
||||
background-color: var(--accent_color_fg);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #279f43;
|
||||
}
|
||||
button:hover {
|
||||
background-color: var(--accent_color_fg_o);
|
||||
}
|
||||
|
||||
.login-text {
|
||||
text-align: center;
|
||||
margin-top: 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.login-text {
|
||||
text-align: center;
|
||||
margin-top: 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.login-text a {
|
||||
color: #0366d6;
|
||||
text-decoration: none;
|
||||
}
|
||||
.login-text a {
|
||||
color: #0366d6;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.login-text a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="signup-card">
|
||||
<h1>Create Account</h1>
|
||||
.login-text a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="signup-card">
|
||||
<h1>Create Account</h1>
|
||||
|
||||
<label for="username">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
autocomplete="username"
|
||||
autocapitalize="off"
|
||||
autocorrect="off"
|
||||
required
|
||||
autofocus
|
||||
/>
|
||||
<label for="username">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
autocomplete="username"
|
||||
autocapitalize="off"
|
||||
autocorrect="off"
|
||||
required
|
||||
autofocus
|
||||
/>
|
||||
|
||||
<label for="password">Password</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
autocomplete="new-password"
|
||||
required
|
||||
/>
|
||||
<label for="password">Password</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
autocomplete="new-password"
|
||||
required
|
||||
/>
|
||||
|
||||
<label for="role">Role</label>
|
||||
<select id="role" name="role" required>
|
||||
<option value="student">Student</option>
|
||||
<option value="professor">Professor</option>
|
||||
</select>
|
||||
<label for="role">Role</label>
|
||||
<select id="role" name="role" required>
|
||||
<option value="student">Student</option>
|
||||
<option value="professor">Professor</option>
|
||||
</select>
|
||||
|
||||
<button type="button" onclick="signup()">Sign up</button>
|
||||
<button type="button" onclick="signup()">Sign up</button>
|
||||
|
||||
<div class="login-text">
|
||||
Already have an account? <a href="login.html">Sign in</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="login-text">Already have an account? <a href="login.html">Sign in</a></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const couchDB = new CouchDB();
|
||||
<script>
|
||||
const couchDB = new CouchDB();
|
||||
|
||||
async function getData() {
|
||||
try {
|
||||
const res = await couchDB.get("users");
|
||||
return res || {};
|
||||
} catch (e) {
|
||||
console.error("Failed to get users:", e);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
async function getData() {
|
||||
try {
|
||||
const res = await couchDB.get("users");
|
||||
return res || {};
|
||||
} catch (e) {
|
||||
console.error("Failed to get users:", e);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
async function signup() {
|
||||
const username = document
|
||||
.getElementById("username")
|
||||
.value.trim()
|
||||
.toLowerCase();
|
||||
const password = document.getElementById("password").value;
|
||||
const role = document.getElementById("role").value;
|
||||
async function signup() {
|
||||
const username = document.getElementById("username").value.trim().toLowerCase();
|
||||
const password = document.getElementById("password").value;
|
||||
const role = document.getElementById("role").value;
|
||||
|
||||
if (!username) {
|
||||
return alert("Please enter a username!");
|
||||
}
|
||||
if (!password) {
|
||||
return alert("Please enter a password!");
|
||||
}
|
||||
if (!username) {
|
||||
return alert("Please enter a username!");
|
||||
}
|
||||
if (!password) {
|
||||
return alert("Please enter a password!");
|
||||
}
|
||||
|
||||
const data = await getData();
|
||||
const data = await getData();
|
||||
|
||||
// Check if user already exists
|
||||
if (data[username]) {
|
||||
return alert("Username already exists!");
|
||||
}
|
||||
// Check if user already exists
|
||||
if (data[username]) {
|
||||
return alert("Username already exists!");
|
||||
}
|
||||
|
||||
// Create new user object
|
||||
data[username] = {
|
||||
password: password,
|
||||
level: 1,
|
||||
avatar: null,
|
||||
abilities: [],
|
||||
enabled_abilities: [],
|
||||
role: role,
|
||||
courses: [],
|
||||
};
|
||||
// Create new user object
|
||||
data[username] = {
|
||||
password: password,
|
||||
level: 1,
|
||||
xp: 0,
|
||||
avatar: null,
|
||||
abilities: [],
|
||||
enabled_abilities: [],
|
||||
role: role,
|
||||
courses: [],
|
||||
};
|
||||
|
||||
try {
|
||||
// Save to database
|
||||
await couchDB.set("users", data);
|
||||
alert("Account created successfully!");
|
||||
try {
|
||||
// Save to database
|
||||
await couchDB.set("users", data);
|
||||
alert("Account created successfully!");
|
||||
|
||||
// Redirect to login page
|
||||
location.href = "./login.html";
|
||||
} catch (e) {
|
||||
console.error("Failed to create account:", e);
|
||||
alert("Failed to create account. Please try again.");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
// Redirect to login page
|
||||
location.href = "./login.html";
|
||||
} catch (e) {
|
||||
console.error("Failed to create account:", e);
|
||||
alert("Failed to create account. Please try again.");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+24
-3
@@ -103,7 +103,7 @@
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
.weiter-btn:hover {
|
||||
background-color: #0056b3;
|
||||
@@ -130,6 +130,7 @@
|
||||
<div class="main-container" id="container2" style="display: none;">
|
||||
<div class="end-dialog">
|
||||
<h2>Vielen Dank für deine Teilnahme!</h2><br>
|
||||
<h3 id="level_up" style="display: none;">Level up!<br><br><br></h3>
|
||||
<button class="weiter-btn" onclick="onEndEvent(this)">
|
||||
Zurück zur Hauptseite
|
||||
</button>
|
||||
@@ -263,7 +264,7 @@ function updateContent(old_page, page) {
|
||||
if (page >= courseData.questions.length) {
|
||||
getId("container1").style.display = "none";
|
||||
getId("container2").style.display = "unset";
|
||||
updateCourseAnswer(finalResult);
|
||||
onFinishEva();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -272,7 +273,15 @@ function updateContent(old_page, page) {
|
||||
getId("content").querySelector(".input").focus();
|
||||
}
|
||||
|
||||
async function onEndEvent(elm) {
|
||||
async function onFinishEva() {
|
||||
await playLevelSound();
|
||||
await updateCourseAnswer(finalResult);
|
||||
if (await levelUpXP(couchDB)) {
|
||||
const lvlElm = getId("level_up");
|
||||
if (lvlElm) lvlElm.style.display = "unset";
|
||||
}
|
||||
}
|
||||
async function onEndEvent() {
|
||||
location.href = "./uebersicht.html?user=" + userData.name;
|
||||
}
|
||||
|
||||
@@ -283,6 +292,18 @@ async function onEndEvent(elm) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!courseData.expire_date) {
|
||||
console.error("courseData.expire_date is null");
|
||||
return;
|
||||
}
|
||||
|
||||
const expire_date = new Date(courseData.expire_date);
|
||||
|
||||
if (courseData.questions.length == 0 || expire_date < new Date()) {
|
||||
onEndEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
finalResult = [];
|
||||
for (var i in courseData.questions) finalResult.push(null);
|
||||
|
||||
|
||||
Reference in new issue
Block a user