166 lines
8.2 KiB
HTML
166 lines
8.2 KiB
HTML
{% extends 'base.html' %}
|
|
|
|
{% block content %}
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
|
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
|
|
crossorigin=""></script>
|
|
<div id="mapquestion-container">
|
|
</div>
|
|
|
|
<div class="container mx-auto px-4">
|
|
<div class="flex justify-between items-center mb-6">
|
|
<h1 class="text-2xl font-bold dark:text-white">{% if question %}Frage bearbeiten{% else %}Neue Karten Frage{% endif %}</h1>
|
|
<a href="{% url 'library:detail_quiz' quiz.id %}"
|
|
class="bg-gray-100 text-gray-700 px-4 py-2 rounded-md hover:bg-gray-200 transition-colors">
|
|
Zurück zum Quiz
|
|
</a>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-md p-6 border-blue-600 border-2 rounded-xl shadow-md dark:bg-transparent dark:text-white">
|
|
<form method="post" class="space-y-6" enctype="multipart/form-data">
|
|
{% csrf_token %}
|
|
|
|
<!-- Question Text -->
|
|
<div>
|
|
<label for="question" class="block text-sm font-medium text-gray-700 dark:text-white">Frage</label>
|
|
<div class="mt-1">
|
|
<textarea name="question" id="question" rows="4"
|
|
class="dark:bg-[#2a2f3a] shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md"
|
|
required>{{ question.data.question }}</textarea>
|
|
</div>
|
|
</div>
|
|
|
|
{% if image %}
|
|
<img src="{{ image.image.url }}" style="max-width: 100px;" alt="Bild der Frage">
|
|
<label for="reset_image">
|
|
<input type="checkbox" name="reset_ques_image" id="reset_ques_image">
|
|
Bild zurücksetzen
|
|
</label>
|
|
{% endif %}
|
|
<div>
|
|
<label class="font-bold" for="question_image">Bild:</label>
|
|
<input class="max-w-full bg-blue-200 p-2 m-2 rounded-lg border-2 border-blue-400 dark:bg-transparent" type="file" name="question_image" id="question_image">
|
|
</div>
|
|
|
|
<label for="map" class="block text-sm font-medium text-gray-700 dark:text-white">Ziel auswählen</label>
|
|
<div id="map"></div>
|
|
|
|
<label for="location" class="block text-sm font-medium text-gray-700 dark:text-white">Koordinaten</label>
|
|
<div class="mt-1">
|
|
<textarea id="location" name="location" rows="2" required
|
|
class="dark:bg-[#2a2f3a] shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md "
|
|
>{{ question.data.target_location }}</textarea>
|
|
</div>
|
|
|
|
<label for="tolerance_radius" class="block text-sm font-medium text-gray-700 dark:text-white">Radius (Meter) für volle Punktzahl</label>
|
|
<div class="mt-1">
|
|
<textarea id="tolerance_radius" name="tolerance_radius" rows="2" required
|
|
class="dark:bg-[#2a2f3a] shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md "
|
|
>{{ question.data.tolerance_radius }}</textarea>
|
|
</div>
|
|
|
|
<div class="p-4">
|
|
<label class="font-bold" for="time_per_question">Zeit pro Frage:</label>
|
|
<select name="time_per_question" id="time_per_question" class="dark:text-white dark:bg-[#2a2f3a] focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
|
<option value="10" {% if standard_time_per_question == "10" or time_per_question == "10" %}selected{% endif %}>10 Sekunden</option>
|
|
<option value="20" {% if standard_time_per_question == "20" or time_per_question == "20" %}selected{% endif %}>20 Sekunden</option>
|
|
<option value="30" {% if standard_time_per_question == "30" or time_per_question == "30" %}selected{% endif %}>30 Sekunden</option>
|
|
<option value="45" {% if standard_time_per_question == "45" or time_per_question == "45" %}selected{% endif %}>45 Sekunden</option>
|
|
<option value="60" {% if standard_time_per_question == "60" or time_per_question == "60" %}selected{% endif %}>1 Minute</option>
|
|
<option value="120" {% if standard_time_per_question == "120" or time_per_question == "120" %}selected{% endif %}>2 Minuten</option>
|
|
<option value="300" {% if standard_time_per_question == "300" or time_per_question == "300" %}selected{% endif %}>5 Minuten</option>
|
|
</select>
|
|
</div>
|
|
|
|
|
|
<label for="credits" class="block text-sm font-medium text-gray-700 dark:text-white">Credits</label>
|
|
<div class="mt-1">
|
|
<textarea name="credits" rows="4"
|
|
class="dark:bg-[#2a2f3a] shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md "
|
|
>{{ credits }}</textarea>
|
|
</div>
|
|
|
|
<div class="flex justify-end space-x-3">
|
|
<a href="{% url 'library:detail_quiz' quiz.id %}"
|
|
class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
|
Abbrechen
|
|
</a>
|
|
<button type="submit"
|
|
class="inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
|
{% if question %}Speichern{% else %}Erstellen{% endif %}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
let marker = null;
|
|
let circle = null;
|
|
const locationInput = document.getElementById('location');
|
|
const radiusInput = document.getElementById('tolerance_radius');
|
|
|
|
const map = L.map('map').setView([51.72, 10.45], 3);
|
|
|
|
// Prüfe, ob Dark Mode aktiv ist
|
|
const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
|
|
// Wähle das passende Karten-Design
|
|
const tileUrl = isDarkMode
|
|
? 'https://{s}.basemaps.cartocdn.com/rastertiles/dark_all/{z}/{x}/{y}.png'
|
|
: 'https://{s}.basemaps.cartocdn.com/rastertiles/light_all/{z}/{x}/{y}.png';
|
|
|
|
L.tileLayer(tileUrl, {
|
|
maxZoom: 19,
|
|
attribution: '© OpenStreetMap © CARTO'
|
|
}).addTo(map);
|
|
|
|
function updateCircle(latlng) {
|
|
const radius = parseInt(radiusInput.value) || 100;
|
|
if (circle) {
|
|
map.removeLayer(circle);
|
|
}
|
|
circle = L.circle(latlng, {
|
|
color: 'blue',
|
|
fillColor: '#87CEEB',
|
|
fillOpacity: 0.2,
|
|
radius: radius
|
|
}).addTo(map);
|
|
}
|
|
|
|
function updateInput(latlng) {
|
|
locationInput.value = `${latlng.lat.toFixed(6)},${latlng.lng.toFixed(6)}`;
|
|
if (marker) {
|
|
updateCircle(marker.getLatLng());
|
|
}
|
|
}
|
|
|
|
function placeOrMoveMarker(latlng) {
|
|
if (marker) {
|
|
marker.setLatLng(latlng);
|
|
} else {
|
|
marker = L.marker(latlng, { draggable: true }).addTo(map);
|
|
|
|
marker.on('dragend', () => {
|
|
updateInput(marker.getLatLng());
|
|
});
|
|
}
|
|
updateInput(latlng);
|
|
}
|
|
|
|
// Update circle when radius changes
|
|
radiusInput.addEventListener('input', () => {
|
|
if (marker) {
|
|
updateCircle(marker.getLatLng());
|
|
}
|
|
});
|
|
|
|
// Place marker at existing coordinates if available
|
|
const existingCoords = '{{ question.data.target_location }}';
|
|
if (existingCoords) {
|
|
const [lat, lng] = existingCoords.split(',').map(Number);
|
|
placeOrMoveMarker({ lat, lng });
|
|
map.setView([lat, lng], 6); // Zoom in to show the marker
|
|
}
|
|
|
|
map.on('click', e => placeOrMoveMarker(e.latlng));
|
|
</script>
|
|
{% endblock %} |