This commit is contained in:
Paul Zinselmeyer 2023-11-01 21:12:18 +01:00
commit d866e4faaa
Signed by: pfzetto
GPG key ID: 4EEF46A5B276E648
19 changed files with 4078 additions and 0 deletions

41
templates/index.stpl Normal file
View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<title>zettoIT ARS</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/pico.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<main class="container">
<p>zettoIT ARS is a lightweight open source audience response system built with rust.</p>
<p>A quiz can be created by uploading a toml-encoded Quizfile. A basic example is listed below:</p>
<code style="width: 100%">
# number of seconds to wait before showing results<br/>
wait_for = 15<br/>
<br/>
[[fields]]<br/>
# name of the field<br/>
name = "Who is there?"<br/>
# array of possible answers<br/>
answers = [ "A", "B", "C", "D"]<br/>
# index (starting at 0) of the correct answer<br/>
correct = 0<br/>
<br/>
[[fields]]<br/>
name = "What is there?"<br/>
answers = [ "A", "B", "C", "D"]<br/>
correct = 0<br/>
</code>
<hr/>
<span id="error" style="color: red;"></span>
<form method="post" hx-post="" hx-target="#error" hx-swap="innerHTML" enctype="multipart/form-data">
<input type="file" name="quizfile"/>
<button type="submit">Quiz erstellen</button>
</form>
</main>
<script src="/static/htmx.min.js"></script>
</body>
</html>

64
templates/play.stpl Normal file
View file

@ -0,0 +1,64 @@
<% if !htmx {%>
<!DOCTYPE html>
<html>
<head>
<title>zettoIT ARS</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/pico.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<main class="container" hx-sse="connect:/<%= id %>/events?player=<%=player_id%> swap:message">
<% } %>
<% if let PlayerState::NotStarted = state { %>
<article>
<center>The Quiz hasn't started yet. Please wait for the first question.</center>
</article>
<% } else if let PlayerState::Answering((field_id, field)) = state { %>
<article>
<h1><%= field.name %></h1>
<% for (index, answer) in field.answers.iter().enumerate() { %>
<form method="POST" hx-post="" hx-target="closest main">
<input type="hidden" name="player_id" value="<%= player_id %>"></input>
<input type="hidden" name="selected" value="<%= index %>"></input>
<button type="submit"><%= answer %></button>
</form>
<% } %>
</article>
<% } else if let PlayerState::Waiting(_) = state{ %>
<article aria-busy="true">
You answered the current question. Please wait for the results.
</article>
<% } else if let PlayerState::Result((field, selected)) = state{ %>
<% if Some(field.correct) == selected { %>
<article>
<center><img src="./static/check.svg" width="50%"/></center>
<center><h1>Correct</h1></center>
<center><p>Your answer is correct. The correct answer is <b><%= field.answers[field.correct as usize] %></b>.</p></center>
</article>
<% } else { %>
<article>
<center><img src="./static/xmark.svg" width="50%"/></center>
<center><h1>Wrong</h1></center>
<center><p>
Your answer is incorrect. The correct answer is <b><%= field.answers[field.correct as usize] %></b>.
<% if let Some(s) = selected { %>
You answered <b><%=field.answers[s as usize]%></b>.
<% } else { %>
You didn't answer the question.
<% } %>
</p></center>
</article>
<% } %>
<% } else if let PlayerState::Completed(correct) = state { %>
<article>
The Quiz finished. You can close this tab now. You answered <b><%= correct*100.0 %>%</b> correctly.
</article>
<% } %>
<% if !htmx { %>
</main>
<script src="/static/htmx.min.js"></script>
</body>
</html>
<% } %>

148
templates/view.stpl Normal file
View file

@ -0,0 +1,148 @@
<% if !htmx {%>
<!DOCTYPE html>
<html>
<head>
<title>zettoIT ARS</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/charts.min.css">
<link rel="stylesheet" href="/static/pico.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<main class="container" hx-sse="connect:/<%= id %>/view/events swap:message">
<% } %>
<h1>zettoIT ARS</h1>
<% if let ViewerState::Answering((current_field, field, data)) = state { %>
<h2><%= field.name%></h2>
<span>Total Participants: <b><%= data.iter().fold(0, |acc, e| acc +e) %></b></span>
<canvas id="myChart"></canvas>
<% if (current_field+1) as usize >= quiz.fields.len() { %>
<button hx-post="" class="outline">End Quiz</button>
<% } else { %>
<button hx-post="" class="outline">Next Question</button>
<% } %>
<script>
var ctx = document.getElementById('myChart');
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: [
<% for answer in field.answers.iter() { %>
"<%= answer %>",
<% } %>
],
datasets: [{
label: "# der Stimmen",
data: [
<% for submissions in data.iter() { %>
<%= submissions %>,
<% } %>
],
borderWidth: 1
}]
},
options: {
legend: {
display: false
},
scales: {
x: {
ticks: {
font: {
size: 64
}
}
},
y: {
beginAtZero: true,
ticks: {
font: {
size:24
}
}
}
}
}
});
</script>
<% } else if let ViewerState::Result((current_field, field, data)) = state { %>
<h2><%= field.name%></h2>
<span>Total Participants: <b><%= data.iter().fold(0, |acc, e| acc +e) %></b></span>
<br/>
<span>The correct answer is: <b><%=field.answers[field.correct as usize]%></b></span>
<canvas id="myChart"></canvas>
<% if (current_field+1) as usize >= quiz.fields.len() { %>
<button hx-post="" class="outline">End Quiz</button>
<% } else { %>
<button hx-post="" class="outline">Next Question</button>
<% } %>
<script>
var ctx = document.getElementById('myChart');
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: [
<% for answer in field.answers.iter() { %>
"<%= answer %>",
<% } %>
],
datasets: [{
label: "# der Stimmen",
data: [
<% for submissions in data.iter() { %>
<%= submissions %>,
<% } %>
],
borderWidth: 1
}]
},
options: {
legend: {
display: false
},
scales: {
x: {
ticks: {
font: {
size: 64
}
}
},
y: {
beginAtZero: true,
ticks: {
font: {
size:24
}
}
}
}
}
});
</script>
<% } else if let ViewerState::NotStarted((player, qrcode, url)) = state { %>
</article>
<center><%- qrcode %></center>
<center><%= url %></center>
<button hx-post="" class="outline">Start Quiz with <b><%= player %></b> Players</button>
</article>
<% } else {%>
<article>
The Quiz finished. You can close this tab now.
</article>
<% } %>
<% if !htmx { %>
</main>
<script src="/static/htmx.min.js"></script>
</body>
</html>
<% } %>