aboutsummaryrefslogtreecommitdiffstats
path: root/templates
diff options
context:
space:
mode:
authorJan T <jan@jantuomi.fi>2024-02-28 17:32:01 +0200
committerJan Tuomi <jan@jantuomi.fi>2024-12-21 19:43:13 +0200
commitb6bc5c5794b4df182175da34e6b08298084c0324 (patch)
tree501362805ac744eb71e0e9d7b70addb9f0c9ae99 /templates
Initial commit
Diffstat (limited to 'templates')
-rw-r--r--templates/base.html.j213
-rw-r--r--templates/error.html.j26
-rw-r--r--templates/index.html.j240
-rw-r--r--templates/manage.html.j2119
-rw-r--r--templates/poll.html.j234
-rw-r--r--templates/poll_confirm_delete.html.j213
-rw-r--r--templates/poll_vote_list.html.j234
-rw-r--r--templates/poll_vote_table.html.j251
8 files changed, 310 insertions, 0 deletions
diff --git a/templates/base.html.j2 b/templates/base.html.j2
new file mode 100644
index 0000000..066c39e
--- /dev/null
+++ b/templates/base.html.j2
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>diddle 👉👈</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
+ <link rel="stylesheet" href="/static/styles.css"></link>
+</head>
+<body>
+ <h1><a href="/">diddle 👉👈</a></h1>
+ {% block content %}{% endblock %}
+</body>
+</html>
diff --git a/templates/error.html.j2 b/templates/error.html.j2
new file mode 100644
index 0000000..2d0dc19
--- /dev/null
+++ b/templates/error.html.j2
@@ -0,0 +1,6 @@
+{% extends "base.html.j2" %}
+
+{% block content %}
+<h2>Error</h2>
+{{ error }}
+{% endblock %}
diff --git a/templates/index.html.j2 b/templates/index.html.j2
new file mode 100644
index 0000000..f84b428
--- /dev/null
+++ b/templates/index.html.j2
@@ -0,0 +1,40 @@
+{% extends "base.html.j2" %}
+
+{% block content %}
+<h2>Create new diddle</h2>
+<form class="poll-form" action="/poll/create" method="post">
+ <table>
+ <tbody>
+ <tr>
+ <td><label for="title">Title</label></td>
+ <td><input type="text" name="title" required></td>
+ </tr>
+ <tr>
+ <td><label for="description">Description (optional)</label></td>
+ <td><textarea name="description"></textarea></td>
+ </tr>
+ <tr>
+ <td><label for="author_name">Your name</label></td>
+ <td><input type="text" name="author_name" required></td>
+ </tr>
+ <tr>
+ <td><label for="author_email">Your email (optional)</label></td>
+ <td><input type="text" name="author_email"></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <p>You can add options after submitting.</p>
+ <input class="green" type="submit" value="Create">
+</form>
+
+{% if created_polls | length != 0 %}
+<h3>My diddles</h3>
+<ul>
+ {% for poll in created_polls %}
+ <li><a href="/manage/{{ poll.manage_code }}">{{ poll.title }}</a></li>
+ {% endfor %}
+</ul>
+{% endif %}
+
+{% endblock %}
diff --git a/templates/manage.html.j2 b/templates/manage.html.j2
new file mode 100644
index 0000000..82f67ea
--- /dev/null
+++ b/templates/manage.html.j2
@@ -0,0 +1,119 @@
+{% extends "base.html.j2" %}
+
+{% block content %}
+
+<h2>Managing poll <span class="contrast">{{ poll.title }}</span> by <i>{{ poll.author_name }}</i></h2>
+
+<p>
+ Share this URL with your peers:<br>
+ <a href="{{ poll.share_url() }}">{{ poll.share_url() }}</a>
+</p>
+<p>
+ <strong>Note!</strong> You can only edit this poll if you have this URL or use the same browser session:<br>
+ <a href="{{ poll.manage_url() }}">{{ poll.manage_url() }}</a>
+</p>
+
+<form class="poll-form" action="/manage/{{ poll.manage_code }}/update_info" method="post">
+ <table>
+ <tbody>
+ <tr>
+ <td><label for="title">Title</label></td>
+ <td><input type="text" name="title" value="{{ poll.title }}" required></td>
+ </tr>
+ <tr>
+ <td><label for="description">Description (optional)</label></td>
+ <td><textarea name="description" value="{{ poll.description }}"></textarea></td>
+ </tr>
+ <tr>
+ <td><label for="author_name">Your name</label></td>
+ <td><input type="text" name="author_name" value="{{ poll.author_name }}" required></td>
+ </tr>
+ <tr>
+ <td><label for="author_email">Your email (optional)</label></td>
+ <td><input type="text" name="author_email" value="{{ poll.author_email }}"></td>
+ </tr>
+ </tbody>
+ </table>
+ <br>
+ <input type="submit" value="Update">
+</form>
+
+<div>
+ <h3>Options</h3>
+</div>
+
+<table class="manage-table">
+ <thead>
+ <tr>
+ <th>Start time</th>
+ <th>End time</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for choice in poll.choices %}
+ <form action="/manage/{{ poll.manage_code }}/delete_choice/{{ choice.id }}" method="post">
+ <tr>
+ <td>
+ <input type="datetime-local" name="start_datetime_{{ choice.id }}" value="{{ choice.start_datetime_notz() }}" disabled
+ {% if last_choice_id == choice.id %}id="last-start-datetime"{% endif %}>
+ </td>
+ <td>
+ <input type="datetime-local" name="end_datetime_{{ choice.id }}" value="{{ choice.end_datetime_notz() }}" disabled
+ {% if last_choice_id == choice.id %}id="last-end-datetime"{% endif %}>
+ </td>
+ <td>
+ <input class="red" type="submit" value="Delete">
+ </td>
+ </tr>
+ </form>
+ {% endfor %}
+ <form action="/manage/{{ poll.manage_code }}/add_choice" method="post">
+ <tr>
+ <td>
+ <input type="datetime-local" name="start_datetime" required>
+ </td>
+ <td>
+ <input type="datetime-local" name="end_datetime" required>
+ </td>
+ <td>
+ <input class="green" type="submit" value="Add">
+ </td>
+ </tr>
+ </form>
+ </tbody>
+</table>
+
+<div class="danger-zone">
+ <h3>Danger zone</h3>
+ <form action="/manage/{{ poll.manage_code }}/delete" method="post">
+ <!-- Empty forms make Lynx use HTTP method GET incorrectly, so we add a useless field -->
+ <input type="hidden" name="poll_id" value="{{ poll.id }}">
+ <input class="red" type="submit" value="Delete poll">
+ </form>
+</div>
+
+<script>
+const hour = 1000 * 60 * 60;
+
+const startDatetimeInput = document.querySelector('input[name="start_datetime"]');
+const endDatetimeInput = document.querySelector('input[name="end_datetime"]');
+
+const lastStartDatetimeInput = document.getElementById('last-start-datetime');
+const lastEndDatetimeInput = document.getElementById('last-end-datetime');
+
+if (lastStartDatetimeInput !== null && startDatetimeInput.valueAsDate === null) {
+ startDatetimeInput.valueAsDate = new Date(lastStartDatetimeInput.valueAsDate.getTime() + hour);
+}
+
+startDatetimeInput.addEventListener('blur', onStartDatetimeBlur);
+
+function onStartDatetimeBlur(event) {
+ const endDatetimeInput = document.querySelector('input[name="end_datetime"]');
+ if (endDatetimeInput.valueAsDate === null) {
+ endDatetimeInput.valueAsDate = new Date(event.target.valueAsDate.getTime() + hour);
+ }
+}
+</script>
+
+{% endblock %} \ No newline at end of file
diff --git a/templates/poll.html.j2 b/templates/poll.html.j2
new file mode 100644
index 0000000..e0ede1f
--- /dev/null
+++ b/templates/poll.html.j2
@@ -0,0 +1,34 @@
+{% extends "base.html.j2" %}
+
+{% block content %}
+
+<h2><span class="contrast">{{ poll.title }}</span> by <i>{{ poll.author_name }}</i></h2>
+{% if poll.description %}
+ <p>{{ poll.description }}</p>
+{% endif %}
+
+{% if poll.choices | length == 0 %}
+<p>No options available.</p>
+{% else %}
+
+<div class="display-mode-section">
+ <form action="/options/toggle_display_mode" method="post">
+ <input type="hidden" name="poll_id" value="{{ poll.id }}">
+ <label>
+ Display mode: <strong>{{ display_mode }}</strong>
+ <input type="submit" value="Toggle">
+ </label>
+ </form>
+</div>
+
+<form action="/poll/{{ poll.id }}/vote" method="post">
+ {% if display_mode == "table" %}
+ {% include "poll_vote_table.html.j2" %}
+ {% else %}
+ {% include "poll_vote_list.html.j2" %}
+ {% endif %}
+</form>
+{% endif %}
+
+
+{% endblock %}
diff --git a/templates/poll_confirm_delete.html.j2 b/templates/poll_confirm_delete.html.j2
new file mode 100644
index 0000000..3a6bc83
--- /dev/null
+++ b/templates/poll_confirm_delete.html.j2
@@ -0,0 +1,13 @@
+{% extends "base.html.j2" %}
+
+{% block content %}
+<h2>Confirm deletion of <span class="contrast">{{ poll.title }}</span></h2>
+
+<p>Are you sure you want to delete {{ poll.title }}?</p>
+
+<form action="/manage/{{ poll.manage_code }}/confirm_delete" method="post">
+ <!-- Empty forms make Lynx use HTTP method GET incorrectly, so we add a useless field -->
+ <input type="hidden" name="poll_id" value="{{ poll.id }}">
+ <input class="red" type="submit" value="Yes, delete it">
+</form>
+{% endblock %}
diff --git a/templates/poll_vote_list.html.j2 b/templates/poll_vote_list.html.j2
new file mode 100644
index 0000000..37b9406
--- /dev/null
+++ b/templates/poll_vote_list.html.j2
@@ -0,0 +1,34 @@
+<div class="vote-list">
+ {% for choice in choices %}
+ <div>
+ <label for="choice_{{ choice.id }}">
+ <input type="checkbox" name="choice_{{ choice.id }}" id="choice_{{ choice.id }}">
+ <strong>
+ {{ choice.start_datetime.strftime("%a %d.%m") }}
+ <span>
+ {% if now.year != choice.start_datetime.year %}.{{choice.start_datetime.year}}{% endif %}
+ </span>
+ <span>
+ {{ choice.start_datetime.strftime("%H:%M") }} &ndash; {{ choice.end_datetime.strftime("%H:%M") }}
+ </span>
+ </strong>
+ <span>
+ <i>{{ choice.votes | length }} votes</i>
+ </span>
+ <div>
+ {% if choice.votes | length != 0 %}
+ Voted by: {% for vote in choice.votes %}{{ vote.voter_name }}{% if not loop.last %}, {% endif %}{% endfor %}
+ {% endif %}
+ <div>
+ </label>
+ </div>
+ <p></p>
+ {% endfor %}
+</div>
+
+<div>
+ <label for="voter_name" hidden>Your name</label>
+ <input type="text" name="voter_name" placeholder="Your name" required>
+ <input class="green" type="submit" value="Submit">
+</div>
+
diff --git a/templates/poll_vote_table.html.j2 b/templates/poll_vote_table.html.j2
new file mode 100644
index 0000000..bfba968
--- /dev/null
+++ b/templates/poll_vote_table.html.j2
@@ -0,0 +1,51 @@
+<table class="vote-table">
+ <tr>
+ <th></th>
+ {% for choice in choices %}
+ <th>
+ {{ choice.start_datetime.strftime("%a %d.%m") }}
+ <span>
+ {% if now.year != choice.start_datetime.year %}.{{choice.start_datetime.year}}{% endif %}
+ </span>
+ <span>
+ {{ choice.start_datetime.strftime("%H:%M") }} &ndash; {{ choice.end_datetime.strftime("%H:%M") }}
+ </span>
+ <span>
+ <i>{{ choice.votes | length }} votes</i>
+ </span>
+ </th>
+ {% endfor %}
+ </tr>
+ {% for voter in choices_by_voter %}
+ <tr>
+ <td>{{ voter.name }}</td>
+ {% for voted in voter.votes %}
+ {% if voted %}
+ <td>
+ <input type="checkbox" checked disabled>
+ </td>
+ {% else %}
+ <td>
+ <input type="checkbox" disabled>
+ </td>
+ {% endif %}
+ {% endfor %}
+ </tr>
+ {% endfor %}
+
+ <!-- Add a row for the current user -->
+ <tr>
+ <td>
+ <label for="voter_name" hidden>Your name</label>
+ <input type="text" name="voter_name" placeholder="Your name" required>
+ </td>
+ {% for choice in choices %}
+ <td>
+ <input type="checkbox" name="choice_{{ choice.id }}">
+ </td>
+ {% endfor %}
+ </tr>
+ <!-- End of the row for the current user -->
+</table>
+
+<input class="green" type="submit" value="Submit">