first backend frontend split
with docker compose file nextjs something something also includes migrations
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
{% load static %}
|
||||
<html>
|
||||
<head>
|
||||
{% include "head.html" %}
|
||||
</head>
|
||||
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
|
||||
<div class="window" id="main-window">
|
||||
<div class="title-bar main-title-bar">
|
||||
<div class="title-bar-text">
|
||||
{% block window-title %}{% endblock %}
|
||||
</div>
|
||||
<div class="title-bar-controls">
|
||||
<button aria-label="Minimize" onclick="resetWindow()"></button>
|
||||
<button aria-label="Restore" onclick="resetWindow()"></button>
|
||||
<form action="{% url 'oidc_logout' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<button aria-label="Close" onclick="hideWindow()"></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="window-body">
|
||||
<menu role="tablist" hx-boost="true" class="multirows">
|
||||
<li role="tab" {% if request.path == '/vote/' %}aria-selected="true" {% endif %}>
|
||||
<a href="{% url 'vote' %}">Stemmen</a>
|
||||
</li>
|
||||
<li role="tab" {% if request.path == '/track/' %}aria-selected="true" {% endif %}>
|
||||
<a href="{% url 'nominate' %}">Nomineren</a>
|
||||
</li>
|
||||
<li role="tab" {% if request.path == '/overview/' %}aria-selected="true" {% endif %}>
|
||||
<a href="{% url 'overview' %}">Overzicht</a>
|
||||
</li>
|
||||
<li role="tab" {% if request.path == '/settings/' %}aria-selected="true" {% endif %}>
|
||||
<a href="{% url 'settings' %}">Instellingen</a>
|
||||
</li>
|
||||
</menu>
|
||||
{% block multi-row %}{% endblock %}
|
||||
<div class="window" role="tabpanel">
|
||||
<div class="window-body">
|
||||
{% if message_type %}
|
||||
<script>
|
||||
function hidePopup() {
|
||||
document.getElementById("info-window").classList.add("hide");
|
||||
}
|
||||
</script>
|
||||
<div class="window popup" id="info-window">
|
||||
<div class="title-bar">
|
||||
<div class="title-bar-text">
|
||||
{% if message_title %}{{message_title}}{% else %}{{message_type | title}}{% endif %}
|
||||
</div>
|
||||
<div class="title-bar-controls">
|
||||
<button aria-label="Close" onclick="hidePopup()"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="window-body">
|
||||
<div class="icon {{message_type}}"></div>
|
||||
<div class="text">
|
||||
<div>
|
||||
{{message}}
|
||||
</div>
|
||||
<section class="field-row" style="justify-content: flex-end">
|
||||
<button onclick="hidePopup()">Ok</button>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% block main-content %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% block status-bar %}{% endblock%}
|
||||
</div>
|
||||
{% block clippy %}{% endblock %}
|
||||
<script>
|
||||
position.get_pos(); // Gets position from localStorage
|
||||
clippy = document.getElementById("clippy")
|
||||
window.addEventListener('load', function () {
|
||||
interact('.main-title-bar').draggable({
|
||||
listeners: {
|
||||
move (event) {
|
||||
position.x += event.dx
|
||||
position.y += event.dy
|
||||
event.target.parentElement.style.transform = `translate(${position.x}px, ${position.y}px)`
|
||||
if (clippy) document.getElementById("clippy").style.transform = `translate(${position.x}px, ${position.y}px)`
|
||||
},
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
function hideWindow() {
|
||||
document.getElementById("main-window").classList.add("hide");
|
||||
}
|
||||
|
||||
function resetWindow() {
|
||||
position.reset()
|
||||
document.getElementById("main-window").style.transform = '';
|
||||
if (clippy) document.getElementById("clippy").style.transform = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
{% load static %}
|
||||
{% if body %}
|
||||
<script>
|
||||
function closeclippy(e) {
|
||||
console.log(e)
|
||||
e.parentElement.classList.add("hide")
|
||||
}
|
||||
</script>
|
||||
<div id="clippy" class="hide">
|
||||
<div class="body">
|
||||
<div class="content">{{ body }}</div>
|
||||
<br /><button onclick="closeclippy(this)">Ok</button>
|
||||
</div>
|
||||
{% if img %}
|
||||
<img src="{% static img %}" />
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -0,0 +1,66 @@
|
||||
{% load static %}
|
||||
<html>
|
||||
<head>
|
||||
{% include "head.html" %}
|
||||
</head>
|
||||
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
|
||||
<script>
|
||||
a = new Audio("{% static 'startup.wav' %}");
|
||||
a.volume = 0.5;
|
||||
a.play();
|
||||
</script>
|
||||
<div class="window popup login" id="info-window">
|
||||
<div class="title-bar">
|
||||
<div class="title-bar-text">Welkom bij Muzak</div>
|
||||
<div class="title-bar-controls">
|
||||
<button aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="window-body">
|
||||
<div class="icon login"></div>
|
||||
<div class="text">
|
||||
<div>
|
||||
<p>Gebruik onderstaande knop om in te loggen.</p>
|
||||
<p>Als je geen inloggegevens hebt, meld je dan bij de beheerder van deze site.</p>
|
||||
<div class="field-row">
|
||||
<form action="{% url 'oidc_authentication_init' %}" method="get">
|
||||
<input type="submit" value="Inloggen" class="default">
|
||||
</form>
|
||||
<button onclick="bsod()">Annuleren</button>
|
||||
<script>
|
||||
function bsod() {
|
||||
var css = document.createElement("link")
|
||||
css.setAttribute("rel", "stylesheet")
|
||||
css.setAttribute("type", "text/css")
|
||||
css.setAttribute("href", "{% static 'bsod.css' %}")
|
||||
document.getElementsByTagName("head")[0].appendChild(css)
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="bsod">
|
||||
<h1>Lekkerste recept voor suikerbrood</h1>
|
||||
<div>* 500 gram bloem</div>
|
||||
<div>* 1 zakje gist</div>
|
||||
<div>* 1 theelepel kaneeel</div>
|
||||
<div>* 3 eetlepels gembersiroop</div>
|
||||
<div>* 200 ml melk</div>
|
||||
<div>* 250 gram kandijsuiker</div>
|
||||
<div>
|
||||
Neem je bloem en zakje gist en meng dit samen met je kaneel in een kom.
|
||||
Maak een kuiltje in het midden en schenk er gembersiroop in en lauwwarme, niet te hete, melk.
|
||||
Meng dit tot deeg, voeg een snufje zout toe en laat dat 15 minuten staan.
|
||||
Kneed het deeg tot een bal en laat het een uur rijzen onder een vochtige theedoek.
|
||||
Maak van het gerezen deeg een dikke lap en verdeel er je suiker over.
|
||||
Rol het geheel weer op en doe het over de lengte in een ingeboterde en ingesuikerde cakevorm.
|
||||
Laat het nog een uurtje rijzen.
|
||||
Bak het in ongeveer 30 minuten in een voorverwarmde oven op 200 graden.
|
||||
Voilà. Suikerbrood. Eet smakelijk.
|
||||
</div>
|
||||
<div class="continue">Druk op F5 om verder te gaan..</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,112 @@
|
||||
{% load static %}
|
||||
<div id="embed"></div>
|
||||
<div id="album">
|
||||
{% if track.album.image %}
|
||||
<img src="{{track.album.image.url}}" />
|
||||
{% elif track.album.image_url %}
|
||||
<img src="{{track.album.image_url}}" />
|
||||
{% else %}
|
||||
<img src="https://kagi.com/proxy/windows-95-logo-png-1.png?c=xjdP8sWN58YWflc6NcGN5ZvzREJyOwtrou-TSsaXxcx37J0VVJbSeycOcAptMJEUpzzvqmbKQ3JRuSmPN8HCK43OxjkRe_cQvncxVzlCblc%3D" />
|
||||
{% endif %}
|
||||
<h1 title="{{track.name}}">{{track.name}}</h1>
|
||||
<h2 title="{{track.artist}}">{{track.artist}}</h2>
|
||||
</div>
|
||||
<input id="seek" type="range" min="0" step="0.1" max="100" value="0" />
|
||||
<div id="media-control" class="waiting">
|
||||
<button id="play"></button>
|
||||
<button id="pause"></button>
|
||||
<button id="stop"></button>
|
||||
<div class="spacer"></div>
|
||||
<button id="prev" class="dummy"></button>
|
||||
<button id="back" class="dummy"></button>
|
||||
<button id="forward" class="dummy"></button>
|
||||
<button id="next" class="dummy"></button>
|
||||
<div class="spacer"></div>
|
||||
<button id="eject" class="dummy"></button>
|
||||
<div class="spacer"></div>
|
||||
<input id="volume" type="range" min="1" max="11" value="5" />
|
||||
</div>
|
||||
<audio id="kankerherrie" loop src="{% static 'kankerherrie.mp3' %}"></audio>
|
||||
<script src="https://open.spotify.com/embed/iframe-api/v1"></script>
|
||||
<script>
|
||||
window.onSpotifyIframeApiReady = doSpotify;
|
||||
doSpotify();
|
||||
function doSpotify (IFrameAPI) {
|
||||
if (IFrameAPI) {
|
||||
ifa = IFrameAPI;
|
||||
} else if (!ifa) return;
|
||||
let element = document.getElementById('embed');
|
||||
let playing = false;
|
||||
let playingPosition = 0;
|
||||
let duration = {{track.duration_ms}};
|
||||
let options = {
|
||||
uri: 'spotify:track:{{track.id}}',
|
||||
height: 152
|
||||
};
|
||||
const callback = (EmbedController) => {
|
||||
document.getElementById("play").addEventListener('click', () => {
|
||||
EmbedController.play();
|
||||
playing = true;
|
||||
if (playingPosition) {
|
||||
setTimeout(() => {
|
||||
EmbedController.seek(parseInt(playingPosition/1000));
|
||||
playingPosition = 0
|
||||
}, 100)
|
||||
}
|
||||
});
|
||||
function pause() {
|
||||
if (playing) {
|
||||
EmbedController.togglePlay();
|
||||
playing = false;
|
||||
}
|
||||
}
|
||||
document.getElementById("pause").addEventListener('click', pause);
|
||||
document.getElementById("stop").addEventListener('click', () => {
|
||||
setTimeout(() => {
|
||||
playingPosition = 0;
|
||||
EmbedController.seek(0);
|
||||
document.getElementById("seek").value = 0;
|
||||
}, 500);
|
||||
pause();
|
||||
});
|
||||
EmbedController.addListener('ready', e => {
|
||||
document.getElementById('media-control').classList.remove('waiting')
|
||||
document.getElementById("seek").addEventListener('change', (e) => {
|
||||
let percentile = parseFloat(e.target.value)/100;
|
||||
EmbedController.seek(duration/1000*percentile);
|
||||
});
|
||||
});
|
||||
EmbedController.addListener('playback_update', e => {
|
||||
duration = e.data.duration;
|
||||
if (playingPosition == 0) document.getElementById('seek').value = `${parseInt(e.data.position) / parseInt(e.data.duration) * 100}`;
|
||||
if (e.data.isPaused) {
|
||||
playingPosition = e.data.position;
|
||||
}
|
||||
else if (playingPosition != 0 && e.data.position != 0) {
|
||||
EmbedController.seek(parseInt(playingPosition/1000));
|
||||
playingPosition = 0;
|
||||
}
|
||||
})
|
||||
};
|
||||
ifa.createController(element, options, callback);
|
||||
iframe = document.getElementsByTagName("iframe")[0]
|
||||
iframe.addEventListener('load', (e) => {
|
||||
console.log(e);
|
||||
iframe.classList.add('hide');
|
||||
});
|
||||
};
|
||||
document.getElementById("volume").addEventListener('input', (event) => {
|
||||
let kankerherrie = document.getElementById("kankerherrie")
|
||||
console.log(event);
|
||||
let volume = event.target.value / 11;
|
||||
event.target.classList.add("playing");
|
||||
event.target.classList.remove("muted");
|
||||
kankerherrie.play();
|
||||
if (volume <= 1/11) {
|
||||
kankerherrie.pause();
|
||||
event.target.classList.remove("playing");
|
||||
event.target.classList.add("muted");
|
||||
}
|
||||
kankerherrie.volume = volume;
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,45 @@
|
||||
{% extends "Base.html" %}
|
||||
|
||||
{% block window-title %}
|
||||
Nomineren
|
||||
{% endblock %}
|
||||
|
||||
{% block main-content %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% if user.profile.can_nominate.0 %}
|
||||
<p>Vul een spotify link in om een nummer te nomineren.</p>
|
||||
<input type="text" id="spotify-input" name="spotify_link" placeholder="Spotify-link">
|
||||
<input type="submit" value="Insturen" {% if user.profile.quota < 1%}disabled{%endif%}>
|
||||
{% elif user.profile.can_nominate.1 == 'quota' %}
|
||||
<p>Je quotum is op. Je zal helaas eventjes moeten wachten met nomineren.</p>
|
||||
{% elif user.profile.can_nominate.1 == 'over' %}
|
||||
<p>Het nomineren is voorbij voor dit jaar! Bedankt voor de inzendingen.</p>
|
||||
{% endif %}
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block status-bar%}
|
||||
<div class="status-bar">
|
||||
<div
|
||||
class="status-bar-field progress-indicator segmented"
|
||||
title="{{user.profile.quota | floatformat:2}} nominaties over."
|
||||
>
|
||||
<span class="progress-indicator-bar" style="width: calc({{user.profile.quota | floatformat:0}} * 18px);" />
|
||||
</div>
|
||||
<p class="status-bar-field">{{user.profile.quota_display}} nominaties over.</p>
|
||||
</div>
|
||||
<div class="status-bar" id="countdown">
|
||||
<p class="status-bar-field"><span id="days"></span> dagen</p>
|
||||
<p class="status-bar-field"><span id="hours"></span> uur</p>
|
||||
<p class="status-bar-field"><span id="minutes"></span> minuten</p>
|
||||
<p class="status-bar-field"><span id="seconds"></span> seconden</p>
|
||||
</div>
|
||||
<script>
|
||||
document.body.addEventListener('htmx:load', function(evt) {
|
||||
//startCountdown("2024-06-25T23:59:59+02:00");
|
||||
startCountdown("{{user.profile.nominate_end}}");
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,45 @@
|
||||
{% extends "Base.html" %}
|
||||
|
||||
{% block window-title %}
|
||||
Overzicht
|
||||
{% endblock %}
|
||||
|
||||
{% block multi-row %}
|
||||
{% comment %} <menu role="tablist" hx-boost="true" class="multirows">
|
||||
<li role="tab" aria-selected="true">
|
||||
<a href="{% url 'overview' %}">Tracks</a>
|
||||
</li>
|
||||
<li role="tab">
|
||||
<a href="{% url 'playlist-list' %}">Playlists</a>
|
||||
</li>
|
||||
</menu> {% endcomment %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main-content %}
|
||||
<p>Onderstaand alle nummers waar je al op gestemd hebt.</p>
|
||||
<ul class="tree-view overview">
|
||||
{% for artist, albums in artists.items %}
|
||||
<li>
|
||||
<details>
|
||||
<summary>{{artist}}</summary>
|
||||
<ul>
|
||||
{% for album, tracks in albums.items %}
|
||||
<li>
|
||||
<details>
|
||||
<summary>{{album}}</summary>
|
||||
<ul>
|
||||
{% for track in tracks %}
|
||||
<li>
|
||||
<a href="{{track.link}}" target="_blank">{{track.name}}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</details>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</details>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,22 @@
|
||||
{% extends "Base.html" %}
|
||||
|
||||
{% block window-title %}
|
||||
Playlist -
|
||||
{% endblock %}
|
||||
|
||||
{% block main-content %}
|
||||
|
||||
{% if tracks %}
|
||||
{% for track in tracks %}
|
||||
<p>{{track}}: {{track.score}}</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
Hoe veel nummers wil je?
|
||||
<input type="number" id="count" name="count">
|
||||
<input type="submit" value="OK" >
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% extends "Base.html" %}
|
||||
|
||||
{% block window-title %}
|
||||
Overzicht - Playlists
|
||||
{% endblock %}
|
||||
|
||||
{% block main-content %}
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,17 @@
|
||||
{% load static %}
|
||||
<script>
|
||||
function hidePopup() {
|
||||
document.getElementById("info-window").classList.add("hide");
|
||||
}
|
||||
</script>
|
||||
<div class="window popup" id="info-window">
|
||||
<div class="title-bar">
|
||||
<div class="title-bar-text">
|
||||
{{title}}
|
||||
<button aria-label="Close" onclick="hidePopup()"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="window-body">
|
||||
{{body}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,74 @@
|
||||
{% extends "Base.html" %}
|
||||
|
||||
{% block window-title %}
|
||||
Instellingen
|
||||
{% endblock %}
|
||||
|
||||
{% block main-content %}
|
||||
<p>Je bent ingelogd als <strong>{{ user.email }}</strong>.</p>
|
||||
{% if user.is_staff %}
|
||||
<form action="{% url 'admin:index' %}">
|
||||
<div class="field-row settings">
|
||||
<label>Administratieve achterkant:</label>
|
||||
<input type="submit" value="" class="icon admin-panel" />
|
||||
</div>
|
||||
</form>
|
||||
<form action="{% url 'playlist-import' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<p>Geef een playlist url om oude nummers te importeren:</p>
|
||||
<input type="text" id="spotify-input" name="playlist_link" placeholder="Spotify-link">
|
||||
<input type="submit" value="Importeer">
|
||||
</form>
|
||||
|
||||
{% comment %} {% if sptDisplayName %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="field-row settings">
|
||||
<label>Spotify gekoppeld:</label>
|
||||
<span>{{sptDisplayName}}</span>
|
||||
<input type="hidden" id="unlink-spotify" name="unlink-spotify" value="true" />
|
||||
<input type="submit" id="spotify-cancel" value=""/>
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="{% url 'spotify-callback' %}">
|
||||
<div class="field-row settings">
|
||||
<label>Link je spotify:</label>
|
||||
<input type="submit" value="" class="icon spotify" />
|
||||
</div>
|
||||
</form>
|
||||
{% endif %} {% endcomment %}
|
||||
{% endif %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% if backgrounds %}
|
||||
<div class="field-row settings">
|
||||
<label for="wallpaper">Wallpaper:</label>
|
||||
<select id="background" name="background" onchange="this.form.submit()">
|
||||
{% for background in backgrounds %}
|
||||
<option
|
||||
value="{{background.id}}"
|
||||
{% if background.id == currentBackground %} selected{% endif %}
|
||||
>
|
||||
{{background.name}}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
</form>
|
||||
<div class="field-row settings">
|
||||
<label>Nominatie quota:</label>
|
||||
<span>{{user.profile.quota|floatformat:3}}</span>
|
||||
</div>
|
||||
<div id="average-stars" style="margin-top:10px;">
|
||||
<fieldset>
|
||||
<legend>Hoeveel sterren geef jij gemiddeld?</legend>
|
||||
<div class="stars">
|
||||
<div class="stars-overlay" style="width: calc({{average}} * 32px)">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,95 @@
|
||||
{% extends "Base.html" %}
|
||||
|
||||
{% block window-title %}
|
||||
Stemmen{% if vote_left or skip_left %}: {{vote_left|add:skip_left}} te gaan.{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main-content %}
|
||||
{% if user.profile.can_vote %}
|
||||
{% if track %}
|
||||
<div id="vote-box" hx-target="body">
|
||||
{% if error %}<div class="error">{{ error }}</div>{% endif %}
|
||||
{% include 'MediaPlayer.html' with track=track %}
|
||||
|
||||
<div
|
||||
id="vote-stars"
|
||||
hx-vals='{"spotify_id": "{{ track.id }}"}'
|
||||
style="margin-top:10px;"
|
||||
>
|
||||
<fieldset>
|
||||
<legend>Hoeveel sterren geef jij dit?</legend>
|
||||
<div class="star-wrapper">
|
||||
<a
|
||||
hx-vals='{"vote": "1"}'
|
||||
hx-post="{% url 'vote' %}"
|
||||
></a>
|
||||
<a
|
||||
hx-vals='{"vote": "2"}'
|
||||
hx-post="{% url 'vote' %}"
|
||||
></a>
|
||||
<a
|
||||
hx-vals='{"vote": "3"}'
|
||||
hx-post="{% url 'vote' %}"
|
||||
></a>
|
||||
<a
|
||||
hx-vals='{"vote": "4"}'
|
||||
hx-post="{% url 'vote' %}"
|
||||
></a>
|
||||
<a
|
||||
hx-vals='{"vote": "5"}'
|
||||
hx-post="{% url 'vote' %}"
|
||||
></a>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="skip-wrapper">
|
||||
{% if not skipped %}
|
||||
{% csrf_token %}
|
||||
<button class="skip" hx-post="{% url 'skip' %}" >Skip</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="undo-wrapper" hx-vals='{"spotify_id": "{{ undo.track.id }}"}' >
|
||||
{% if undo %}
|
||||
{% csrf_token %}
|
||||
<p>Je hebt {{undo.track}} een score van {{undo.points}} sterren gegeven!</p>
|
||||
<button class="undo" hx-post="{% url 'undo' %}" >Undo</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p hx-boost="true">
|
||||
Je hebt niets meer om te stemmen. Lekker bezig!
|
||||
<a href="{% url 'nominate' %}">Nomineer zelf iets</a>, als je nog quota hebt.
|
||||
</p>
|
||||
{% if undo %}
|
||||
<!--<form class="undo-wrapper" method="post" action="{% url 'undo' %}" hx-vals='{"spotify_id": "{{ undo.track.id }}"}' >-->
|
||||
<div class="undo-wrapper" hx-target="body" hx-vals='{"spotify_id": "{{ undo.track.id }}"}' >
|
||||
{% csrf_token %}
|
||||
<p>Je hebt {{undo.track}} een score van {{undo.points}} sterren gegeven!</p>
|
||||
<button class="undo" hx-post="{% url 'undo' %}" >Undo</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<p> Stemmen is voorbij. Joe.</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block clippy %}
|
||||
{% include "Clippy.html" with body=track.banter img="img/draakje/draakje-headphones3.gif" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block status-bar%}
|
||||
<div class="status-bar" id="countdown">
|
||||
<p class="status-bar-field"><span id="days"></span> dagen</p>
|
||||
<p class="status-bar-field"><span id="hours"></span> uur</p>
|
||||
<p class="status-bar-field"><span id="minutes"></span> minuten</p>
|
||||
<p class="status-bar-field"><span id="seconds"></span> seconden</p>
|
||||
</div>
|
||||
<script>
|
||||
document.body.addEventListener('htmx:load', function(evt) {
|
||||
//startCountdown("2024-08-25T23:59:59+02:00");
|
||||
startCountdown("{{user.profile.vote_end}}");
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,16 @@
|
||||
{% load static %}
|
||||
|
||||
body {
|
||||
{% if background.image %}
|
||||
background-image: url('{{background.image.url}}');
|
||||
{% endif %}
|
||||
{% if not background.repeat %}
|
||||
background-repeat: no-repeat;
|
||||
{% endif %}
|
||||
{% if background.cover %}
|
||||
background-size: cover;
|
||||
{% endif %}
|
||||
{% if background.color %}
|
||||
background-color: {{background.color}} !important;
|
||||
{% endif %}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
{% load static %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="{% static 'js/htmx.min.js' %}" defer></script>
|
||||
<script src="{% static 'js/interact.js' %}" defer></script>
|
||||
<script src="{% static 'js/countdown.js' %}" defer></script>
|
||||
<link href="{% static '98.css/style.css' %}" rel="stylesheet" type="text/css" />
|
||||
<link href="{% static 'style.css'%}" rel="stylesheet" type="text/css" />
|
||||
<style>
|
||||
{% include 'background.css' with background=user.profile.background %}
|
||||
</style>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'apple-touch-icon.png' %}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'favicon-32x32.png' %}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'favicon-16x16.png' %}">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<title>HD Muzak</title>
|
||||
<script>
|
||||
//Global position object for cross-page window positioning
|
||||
position = {
|
||||
set x(val) {
|
||||
this._x = val
|
||||
localStorage.setItem("position", JSON.stringify({x: val, y: this._y}));
|
||||
},
|
||||
set y(val) {
|
||||
this._y = val
|
||||
localStorage.setItem("position", JSON.stringify({x: this._x, y: val}));
|
||||
},
|
||||
get x() { return this._x },
|
||||
get y() { return this._y },
|
||||
_x: 0, _y: 0,
|
||||
get_pos() {
|
||||
stored_position = JSON.parse(localStorage.getItem("position"));
|
||||
if (stored_position == null) {
|
||||
localStorage.removeItem("position")
|
||||
position.x = 0;
|
||||
position.y = 0;
|
||||
} else {
|
||||
position.x = stored_position.x
|
||||
position.y = stored_position.y
|
||||
}
|
||||
document.getElementById("main-window").style.transform =
|
||||
`translate(${position.x}px, ${position.y}px)`
|
||||
clippy = document.getElementById("clippy")
|
||||
if (clippy) {
|
||||
clippy.style.transform =
|
||||
`translate(${position.x}px, ${position.y}px)`
|
||||
clippy.classList.remove('hide');
|
||||
}
|
||||
},
|
||||
reset() {
|
||||
this._x = 0
|
||||
this._y = 0
|
||||
localStorage.removeItem("position")
|
||||
}
|
||||
}
|
||||
|
||||
//global spotify IFrameAPI cache
|
||||
ifa = null;
|
||||
</script>
|
||||
Reference in New Issue
Block a user