Compare commits
2 Commits
64-footer-
...
testbranhc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e135ff945f | ||
|
|
fbb0787aa9 |
@@ -6,10 +6,9 @@ class QivipQuizAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'user_id', 'status', 'category', 'creation_date', 'update_date') # Welche Felder sollen in der Übersicht angezeigt werden
|
||||
search_fields = ('name', 'user_id__username', 'category__name') # Suchfelder
|
||||
list_filter = ('status', 'category') # Filteroptionen
|
||||
|
||||
# Für das QivipQuestion Modell
|
||||
class QivipQuestionAdmin(admin.ModelAdmin):
|
||||
list_display = ('id', 'quiz_id', 'data', 'creation_date', 'update_date')
|
||||
list_display = ('quiz_id', 'data', 'creation_date', 'update_date')
|
||||
search_fields = ('data',)
|
||||
list_filter = ('quiz_id',)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from .models import QivipQuiz, QivipQuestion
|
||||
class QuizForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = QivipQuiz
|
||||
fields = ['name', 'description','image', 'status', 'category', 'tags',"difficulty"]
|
||||
fields = ['name', 'description','image', 'status', 'category', 'tags',"difficulty","credits"]
|
||||
|
||||
class QuestionForm(forms.ModelForm):
|
||||
class Meta:
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.7 on 2025-04-03 16:46
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('library', '0024_alter_qivipquiz_image'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='qivipquiz',
|
||||
name='modified_description',
|
||||
field=models.TextField(blank=True, default='Das Quiz wurde modifiziert von:', editable=False),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.7 on 2025-04-04 13:28
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('library', '0025_qivipquiz_modified_description'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='qivipquiz',
|
||||
name='modified_description',
|
||||
field=models.TextField(blank=True, editable=False),
|
||||
),
|
||||
]
|
||||
21
django/library/migrations/0027_qivipquiz_creator.py
Normal file
21
django/library/migrations/0027_qivipquiz_creator.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# Generated by Django 5.1.7 on 2025-04-04 13:37
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('library', '0026_alter_qivipquiz_modified_description'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='qivipquiz',
|
||||
name='creator',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='creator_quiz', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
21
django/library/migrations/0028_alter_qivipquiz_creator.py
Normal file
21
django/library/migrations/0028_alter_qivipquiz_creator.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# Generated by Django 5.1.7 on 2025-04-04 13:57
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('library', '0027_qivipquiz_creator'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='qivipquiz',
|
||||
name='creator',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='creator_quiz', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
18
django/library/migrations/0029_qivipquiz_credits.py
Normal file
18
django/library/migrations/0029_qivipquiz_credits.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.7 on 2025-04-04 16:02
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('library', '0028_alter_qivipquiz_creator'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='qivipquiz',
|
||||
name='credits',
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,27 @@
|
||||
# Generated by Django 5.1.7 on 2025-04-05 09:39
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('library', '0029_qivipquiz_credits'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='qivipquiz',
|
||||
name='creator',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='qivipquiz',
|
||||
name='modified_description',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='qivipquiz',
|
||||
name='base_quiz',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='child_quizzes', to='library.qivipquiz'),
|
||||
),
|
||||
]
|
||||
@@ -27,6 +27,8 @@ class QivipQuiz(models.Model):
|
||||
image = models.ImageField(max_length=256, upload_to='quiz_images/', blank=True, null=True) # Bild speichern in media/quiz_images/
|
||||
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
|
||||
user_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name='quiz')
|
||||
#creator = models.ForeignKey(User, on_delete=models.SET_NULL,blank=True, null=True, related_name='creator_quiz')
|
||||
base_quiz = models.ForeignKey('self', on_delete=models.SET_NULL,blank=True, null=True, related_name='child_quizzes')
|
||||
creation_date = models.DateTimeField(auto_now_add=True)
|
||||
update_date = models.DateTimeField(auto_now=True)
|
||||
status = models.CharField(max_length=10, choices=list(STATUS_VALUES.items()), default="öffentlich")
|
||||
@@ -35,11 +37,13 @@ class QivipQuiz(models.Model):
|
||||
name = models.CharField(max_length=75)
|
||||
description = models.TextField(validators=[validate_description],max_length=200,blank=False, default="In dem Quiz geht es um ...")
|
||||
difficulty= models.CharField(max_length=13, choices=list(DIFFICULTY_VALUES.items()), default="nicht gesetzt", help_text="1: niedrigste Schwierigkeit und 5: höchste Schwierigkeit")
|
||||
|
||||
credits=models.TextField(blank=True, editable=True)
|
||||
def __str__(self):
|
||||
|
||||
return self.name
|
||||
|
||||
|
||||
|
||||
# Create your models here.
|
||||
class QivipQuestion(models.Model):
|
||||
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
|
||||
|
||||
@@ -14,6 +14,8 @@ urlpatterns = [
|
||||
path('question/new/', views.new_question, name='new_question'),
|
||||
path('question/edit/<int:pk>/', views.edit_question, name='edit_question'),
|
||||
path('question/delete/<int:pk>/', views.delete_question, name='delete_question'),
|
||||
path('detail/copy/<int:pk>/', views.copy_quiz, name='copy_quiz'),
|
||||
|
||||
]# Nur für die Entwicklungsumgebung
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import uuid
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import User
|
||||
@@ -26,7 +27,6 @@ def overview_quiz(request):
|
||||
filter_my_quizzes = QivipQuiz.objects.none()
|
||||
|
||||
filter_other_quizzes = QivipQuiz.objects.annotate(max_amout_questions=Count('question'))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -67,13 +67,14 @@ def overview_quiz(request):
|
||||
except:
|
||||
filter_other_quizzes=filter_other_quizzes
|
||||
|
||||
# Anzahl der Quiz pro Seite für Swiper
|
||||
|
||||
print("kein Filter ,form_valid")
|
||||
|
||||
filter_other_quizzes = filter_other_quizzes.filter(max_amout_questions__gte=1).filter(status='öffentlich')
|
||||
|
||||
context = {
|
||||
'show_search': True,
|
||||
'filter_my_quizzes': filter_my_quizzes,
|
||||
'filter_other_quizzes': filter_other_quizzes,
|
||||
'filter_my_quizzes': filter_my_quizzes.order_by('-creation_date'),
|
||||
'filter_other_quizzes': filter_other_quizzes.order_by('-creation_date'),
|
||||
'form': form,
|
||||
}
|
||||
|
||||
@@ -91,6 +92,7 @@ def new_quiz(request):
|
||||
if form.is_valid():
|
||||
quiz = form.save(commit=False)
|
||||
quiz.user_id = request.user
|
||||
quiz.creator = request.user
|
||||
quiz.save()
|
||||
form.save_m2m() # Speichert die Many-to-Many Beziehungen (Tags)
|
||||
return redirect('library:detail_quiz', pk=quiz.pk)
|
||||
@@ -106,12 +108,15 @@ def edit_quiz(request, pk):
|
||||
if request.method == 'POST':
|
||||
form = QuizForm(request.POST, instance=quiz, files=request.FILES)
|
||||
if form.is_valid():
|
||||
|
||||
form.save()
|
||||
return redirect('library:detail_quiz', pk=quiz.pk)
|
||||
return redirect('library:detail_quiz', pk=pk)
|
||||
#return modified(request, pk)
|
||||
|
||||
else:
|
||||
form = QuizForm(instance=quiz)
|
||||
return render(request, 'library/form.html', {'form': form})
|
||||
|
||||
|
||||
# Quiz löschen
|
||||
@login_required
|
||||
def delete_quiz(request, pk):
|
||||
@@ -122,9 +127,9 @@ def delete_quiz(request, pk):
|
||||
return render(request, 'library/delete_confirmation.html', {'object': quiz})
|
||||
|
||||
# Quiz anzeigen
|
||||
@login_required
|
||||
def detail_quiz(request, pk):
|
||||
quiz = get_object_or_404(QivipQuiz, pk=pk, user_id=request.user)
|
||||
#quiz = get_object_or_404(QivipQuiz, pk=pk, user_id=request.user)
|
||||
quiz = get_object_or_404(QivipQuiz, pk=pk)
|
||||
questions = QivipQuestion.objects.filter(quiz_id=quiz)
|
||||
|
||||
# Parse JSON data for each question
|
||||
@@ -137,6 +142,63 @@ def detail_quiz(request, pk):
|
||||
'questions': questions
|
||||
}
|
||||
return render(request, 'library/detail_quiz.html', context)
|
||||
"""
|
||||
def modified(request, pk):
|
||||
|
||||
original_quiz = get_object_or_404(QivipQuiz, pk=pk)
|
||||
words=original_quiz.modified_description.split()
|
||||
word_exist=0
|
||||
print(original_quiz.creator.username)
|
||||
print(request.user.username)
|
||||
|
||||
for word in words:
|
||||
|
||||
if word==request.user.username or word+","==request.user.username:
|
||||
word_exist=1
|
||||
|
||||
|
||||
if word_exist==0 and len(words)!=0 and request.user.username!=original_quiz.creator.username:
|
||||
original_quiz.modified_description +=", "+ request.user.username
|
||||
|
||||
|
||||
elif word_exist==0 and request.user.username!=original_quiz.creator.username:
|
||||
original_quiz.modified_description +=" "+ request.user.username
|
||||
|
||||
original_quiz.save()
|
||||
|
||||
return redirect('library:detail_quiz', pk=pk)
|
||||
|
||||
"""
|
||||
|
||||
@login_required
|
||||
def copy_quiz(request, pk):
|
||||
original_quiz = get_object_or_404(QivipQuiz, pk=pk)
|
||||
|
||||
|
||||
# Quiz kopieren (ohne ID, damit ein neues Objekt erstellt wird)
|
||||
|
||||
# Quiz kopieren (ohne ID, damit ein neues Objekt erstellt wird)
|
||||
|
||||
new_quiz = original_quiz # Kopie erstellen (aber Achtung: Noch gleiche Referenz!)
|
||||
new_quiz.pk = None # Setzt die ID auf None, damit Django es als neues Objekt erkennt
|
||||
new_quiz.uuid = uuid.uuid4() # Neue UUID generieren
|
||||
new_quiz.user_id = request.user # Neuer Besitzer ist der aktuelle User
|
||||
new_quiz.name += " - Kopie" # Optional: Name anpassen
|
||||
new_quiz.base_quiz_id = pk
|
||||
#new_quiz.creator = original_quiz.creator or request.user
|
||||
new_quiz.save() # Speichern als neues Objekt
|
||||
# Optional: Beschreibung anpassen
|
||||
# Alle zugehörigen Fragen kopieren
|
||||
questions = QivipQuestion.objects.filter(quiz_id=pk)
|
||||
for question in questions:
|
||||
question.uuid = uuid.uuid4()
|
||||
question.pk = None # Setze pk auf None, damit es als neues Objekt gespeichert wird
|
||||
question.quiz_id = original_quiz # Verknüpfe mit dem neuen Quiz
|
||||
question.data = question.data # `data`-Feld wird explizit übernommen # Verknüpfe mit dem neuen Quiz
|
||||
question.save()
|
||||
|
||||
return redirect('library:detail_quiz', pk=new_quiz.pk)
|
||||
|
||||
|
||||
# Übersicht aller Fragen
|
||||
@login_required
|
||||
@@ -212,6 +274,7 @@ def new_question(request):
|
||||
question.data = json.dumps(json_data)
|
||||
question.quiz_id = quiz
|
||||
question.save()
|
||||
#return modified(request, pk=quiz.pk)
|
||||
return redirect('library:detail_quiz', pk=quiz.pk)
|
||||
else:
|
||||
# Initialize empty question data for new questions
|
||||
@@ -340,7 +403,9 @@ def edit_question(request, pk):
|
||||
|
||||
question.data = json.dumps(json_data)
|
||||
question.save()
|
||||
#return modified(request, question.quiz_id.pk)
|
||||
return redirect('library:detail_quiz', pk=question.quiz_id.pk)
|
||||
|
||||
else:
|
||||
template_name = f'library/question/question_{question_type}.html'
|
||||
context = {
|
||||
@@ -351,6 +416,7 @@ def edit_question(request, pk):
|
||||
|
||||
return render(request, template_name, context)
|
||||
|
||||
|
||||
# Frage löschen
|
||||
@login_required
|
||||
def delete_question(request, pk):
|
||||
|
||||
@@ -4,9 +4,7 @@ from . import views
|
||||
app_name = 'play'
|
||||
|
||||
urlpatterns = [
|
||||
path('game/<str:join_code>', views.lobby, name='lobby'),
|
||||
path('game/<str:join_code>/participate', views.create_participant, name='create_participant'),
|
||||
path('lobby/<str:join_code>', views.lobby, name='lobby'),
|
||||
path('lobby/<str:join_code>/participate', views.create_participant, name='create_participant'),
|
||||
path('join', views.join_game, name='join_game'),
|
||||
path('game/<str:join_code>/<int:question_id>', views.question, name='question'),
|
||||
path('game/<str:join_code>/<int:question_id>/participant', views.question_participant, name='question_participant'),
|
||||
]
|
||||
@@ -1,11 +1,9 @@
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import render, redirect, get_object_or_404, reverse
|
||||
from play.models import QuizGame, QuizGameParticipant
|
||||
from library.models import QivipQuiz, QivipQuestion
|
||||
from library.models import QivipQuiz
|
||||
from django.http import HttpResponseRedirect
|
||||
|
||||
import json
|
||||
|
||||
# Create your views here.
|
||||
def lobby(request, join_code):
|
||||
if not "participant_id" in request.COOKIES:
|
||||
@@ -59,28 +57,4 @@ def join_game(request):
|
||||
except QuizGame.DoesNotExist:
|
||||
# TODO: Mit message eine Fehlermeldung weitergeben (und im entsprechenden Template Designen)
|
||||
pass
|
||||
return render(request, 'play/join_game.html')
|
||||
|
||||
def question(request, join_code, question_id):
|
||||
question = get_object_or_404(QivipQuestion, pk=question_id)
|
||||
|
||||
if question.data:
|
||||
question.data = json.loads(question.data)
|
||||
|
||||
context = {
|
||||
'question': question,
|
||||
}
|
||||
|
||||
return render(request, 'play/game/question_host.html', {'question': question, 'debug': "debug"})
|
||||
|
||||
def question_participant(request, join_code, question_id):
|
||||
question = get_object_or_404(QivipQuestion, pk=question_id)
|
||||
|
||||
if question.data:
|
||||
question.data = json.loads(question.data)
|
||||
|
||||
context = {
|
||||
'question': question,
|
||||
}
|
||||
|
||||
return render(request, 'play/game/question_participant.html', {'question': question, 'debug': "debug"})
|
||||
return render(request, 'play/join_game.html')
|
||||
@@ -50,61 +50,4 @@ a.qp-a-button-small {
|
||||
.input-group form p button {
|
||||
@apply p-3 rounded-full bg-indigo-500 hover:bg-indigo-600 text-white focus:scale-105
|
||||
transition duration-200 font-black shadow-md hover:shadow-lg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
div.qp-answer-container {
|
||||
@apply grid grid-cols-2 h-screen;
|
||||
}
|
||||
|
||||
div.qp-answer-container div {
|
||||
@apply grid place-content-center rounded-xl m-2 place-self-stretch text-white transition duration-300;
|
||||
@apply nth-1:bg-green-500 hover:nth-1:bg-green-600;
|
||||
@apply nth-2:bg-red-500 hover:nth-2:bg-red-600;
|
||||
@apply nth-3:bg-blue-500 hover:nth-3:bg-blue-600;
|
||||
@apply nth-4:bg-yellow-500 hover:nth-4:bg-yellow-600;
|
||||
@apply nth-5:bg-purple-500 hover:nth-5:bg-purple-600;
|
||||
@apply nth-6:bg-black hover:nth-6:bg-slate-800;
|
||||
}
|
||||
|
||||
div.qp-answer-container div p {
|
||||
@apply font-black text-xl sm:text-2xl md:text-4xl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
div.qp-answer-container-host {
|
||||
@apply grid grid-cols-2 absolute bottom-0 w-screen xl:px-20 xl:pb-10;
|
||||
}
|
||||
|
||||
div.qp-answer-container-host div {
|
||||
@apply grid place-content-center rounded-xl m-1 place-self-stretch text-white transition duration-300;
|
||||
@apply nth-1:bg-green-500 hover:nth-1:bg-green-600;
|
||||
@apply nth-2:bg-red-500 hover:nth-2:bg-red-600;
|
||||
@apply nth-3:bg-blue-500 hover:nth-3:bg-blue-600;
|
||||
@apply nth-4:bg-yellow-500 hover:nth-4:bg-yellow-600;
|
||||
@apply nth-5:bg-purple-500 hover:nth-5:bg-purple-600;
|
||||
@apply nth-6:bg-black hover:nth-6:bg-slate-800;
|
||||
}
|
||||
|
||||
div.qp-answer-container-host div p {
|
||||
@apply font-black text-xl p-4;
|
||||
}
|
||||
|
||||
div.qp-question-container {
|
||||
@apply text-center text-3xl px-4 py-9 h-screen;
|
||||
}
|
||||
|
||||
div.qp-question-container img {
|
||||
@apply max-w-[50vw] max-h-[40vh] mx-auto;
|
||||
}
|
||||
@@ -10,13 +10,8 @@
|
||||
</head>
|
||||
<body>
|
||||
{% include 'partials/_nav.html' %}
|
||||
<div class="flex flex-col h-screen overflow-x-hidden">
|
||||
{% block content%}{% endblock %}
|
||||
<div class="fixed bottom-0 w-full">
|
||||
{% include 'partials/_footer.html' %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% block content%}{% endblock %}
|
||||
{% include 'partials/_footer.html' %}
|
||||
{% block extra_js %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +1,13 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-2xl font-bold">{{ quiz.name }}</h1>
|
||||
<div class="flex space-x-2">
|
||||
{% if quiz.user_id == request.user %}
|
||||
<a href="{% url 'library:edit_quiz' quiz.id %}" class=" text-white px-4 py-2 rounded-md text-sm lg:text-lg hover:scale-110 transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-7 text-gray-600">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
||||
@@ -16,26 +19,35 @@
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
|
||||
</svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="{% url 'library:copy_quiz' quiz.id %}" class="flex items-center qp-a-button-small border-2 border-blue-600 text-gray-600 font-bold drop-shadow-lg custom-outline">Quiz kopieren</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if quiz.description %}
|
||||
<p class="text-gray-600 mb-8">{{ quiz.description }}</p>
|
||||
<p class="text-gray-600 mb-4">{{ quiz.description }}</p>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
<div class="bg-white rounded-lg shadow-md border-blue-600 border-2 rounded-xl shadow-md">
|
||||
<div class="border-b border-gray-200 p-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<h2 class="text-xl font-semibold">Fragen</h2>
|
||||
<div class="flex space-x-2">
|
||||
{% if quiz.user_id == request.user %}
|
||||
<a href="{% url 'library:new_question' %}?type=multiple_choice&quiz_id={{ quiz.id }}"
|
||||
class="bg-blue-100 text-blue-800 px-4 py-2 rounded-md text-xs lg:text-lg hover:border-blue-600 border-2">
|
||||
Multiple Choice
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if quiz.user_id == request.user %}
|
||||
<a href="{% url 'library:new_question' %}?type=true_false&quiz_id={{ quiz.id }}"
|
||||
class="bg-purple-100 text-purple-800 px-4 py-2 rounded-md text-xs lg:text-lg hover:border-blue-600 border-2">
|
||||
Wahr/Falsch
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -46,7 +58,7 @@
|
||||
{% for question in questions %}
|
||||
|
||||
<div class="w-full rounded-xl p-4 hover:bg-gray-50">
|
||||
<a class="block flex h-full w-full" href="{% url 'library:edit_question' question.id %}" >
|
||||
{% if quiz.user_id == request.user %} <a class="block flex h-full w-full" href="{% url 'library:edit_question' question.id %}" > {% endif %}
|
||||
<div class="flex justify-between items-start">
|
||||
|
||||
<div class="flex-grow">
|
||||
@@ -89,20 +101,15 @@
|
||||
</div>
|
||||
|
||||
<div class="flex h-full space-x-2 ml-4 items-center">
|
||||
<!--
|
||||
<a href="{% url 'library:edit_question' question.id %}"
|
||||
class="bg-gray-100 text-gray-700 px-3 py-1 rounded hover:bg-gray-200 transition-colors">
|
||||
Bearbeiten
|
||||
</a>
|
||||
-->
|
||||
|
||||
|
||||
<a href=" {% url 'library:delete_question' question.id %}"
|
||||
class=" text-red-700 px-4 py-1 rounded hover:scale-110 ">
|
||||
{% if quiz.user_id == request.user %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-7 text-gray-600">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
|
||||
</svg>
|
||||
|
||||
</a>
|
||||
{% endif %}
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -122,5 +129,23 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
{% if quiz.base_quiz %}
|
||||
<p class="text-gray-600 mt-2 ">Kopie von: <a href="{% url 'library:detail_quiz' quiz.base_quiz.id %}"><span class="font-bold">{{ quiz.base_quiz}}</span></a></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
{% if quiz.base_quiz %}
|
||||
<p class="text-gray-600 mb-2">Autor:<span class="font-bold"> {{ quiz.base_quiz.user_id}}</span></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
{% if quiz.credits %}
|
||||
<p class="text-gray-600 mb-2">Credits:<span class="font-bold"> {{ quiz.credits }}</span></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -61,20 +61,33 @@
|
||||
{% if quiz.image %} style="background-image: url('http://127.0.0.1:8000/library{{ quiz.image.url }}');" {% endif %}>
|
||||
<div class="absolute inset-0 bg-gray-900/60 bg-opacity-50 rounded-lg"></div>
|
||||
|
||||
<h2 class=" font-bold break-words truncate text-white font-bold text-white drop-shadow-lg custom-outline"> <a href="{% url 'library:detail_quiz' quiz.id %}">{{ quiz.name }}</a></h2>
|
||||
<h2 class=" break-words truncate text-white drop-shadow-lg custom-outline"> <a href="{% url 'library:detail_quiz' quiz.id %}">{{ quiz.name }}</a></h2>
|
||||
|
||||
<p class="text-white font-bold text-white drop-shadow-lg custom-outline">
|
||||
<span class="break-words line-clamp-2 ">{{ quiz.description }}</span><br>
|
||||
Schwierigkeit: <span class="font-bold">{{ quiz.difficulty }}</span><br>
|
||||
Anzahl der Fragen: <span class="font-bold ">{{ quiz.question.count }}</span><br>
|
||||
Status: <span class="font-bold ">{{ quiz.status }}</span>
|
||||
|
||||
|
||||
<p class=" font-bold break-words truncate text-white drop-shadow-lg custom-outline">
|
||||
{% if quiz.authors.all %}
|
||||
Autor(en):
|
||||
{% for author in quiz.authors.all %}
|
||||
|
||||
{{ author.username }}{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
|
||||
</p>
|
||||
|
||||
<!-- Buttons bleiben am unteren Rand -->
|
||||
<div class="flex justify-between items-center gap-2 ">
|
||||
<a href="#" class="qp-a-button-small border-2 border-blue-600 text-white font-bold text-white drop-shadow-lg custom-outline">Spiel starten</a>
|
||||
<div class="flex gap-2">
|
||||
<a href="{% url 'library:detail_quiz' quiz.id %}" class="qp-a-button-small border-2 border-blue-600 text-white text-white font-bold text-white drop-shadow-lg custom-outline">
|
||||
<a href="{% url 'library:detail_quiz' quiz.id %}" class="qp-a-button-small border-2 border-blue-600 text-white font-bold drop-shadow-lg custom-outline">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-7">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
||||
</svg>
|
||||
@@ -118,7 +131,7 @@
|
||||
{% if quiz.image %} style="background-image: url('http://127.0.0.1:8000/library{{ quiz.image.url }}');" {% endif %}>
|
||||
<div class="absolute inset-0 bg-gray-900/60 bg-opacity-50 rounded-lg"></div>
|
||||
|
||||
<h2 class=" font-bold break-words truncate text-white font-bold text-white drop-shadow-lg custom-outline"> <a href="{% url 'library:detail_quiz' quiz.id %}">{{ quiz.name }}</a></h2>
|
||||
<h2 class="break-words truncate text-white drop-shadow-lg custom-outline"> <a href="{% url 'library:detail_quiz' quiz.id %}">{{ quiz.name }}</a></h2>
|
||||
|
||||
<p class="text-white font-bold text-white drop-shadow-lg custom-outline">
|
||||
<span class="break-words line-clamp-2 ">{{ quiz.description }}</span><br>
|
||||
@@ -126,19 +139,23 @@
|
||||
Anzahl der Fragen: <span class="font-bold ">{{ quiz.question.count }}</span><br>
|
||||
Erstellt am: <span class="font-bold ">{{ quiz.creation_date }}</span>
|
||||
</p>
|
||||
{% if quiz.original_creator %}
|
||||
<p class=" font-bold break-words truncate text-white drop-shadow-lg custom-outline">Ursprünglich erstellt von: {{ quiz.original_creator }}</p>
|
||||
{% endif %}
|
||||
|
||||
<!-- Buttons bleiben am unteren Rand -->
|
||||
<div class="flex justify-between items-center gap-2 ">
|
||||
<a href="#" class="qp-a-button-small border-2 border-blue-600 text-white font-bold text-white drop-shadow-lg custom-outline">Spiel starten</a>
|
||||
<a href="{% url 'library:detail_quiz' quiz.id %}" class="qp-a-button-small border-2 border-blue-600 text-white text-white font-bold text-white drop-shadow-lg custom-outline">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-7">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
||||
</svg>
|
||||
|
||||
</a>
|
||||
<div class="flex gap-2">
|
||||
<a href="{% url 'library:overview_quiz' %}?user={{ quiz.user_id }}" class="text-gray-600 text-sm">
|
||||
<button type="submit" class=" text-sm py-1 text-white font-bold text-white drop-shadow-lg custom-outline hover:text-gray-300"> Quiz von {{ quiz.user_id }}</button>
|
||||
<a href="{% url 'library:overview_quiz' %}?user={{ quiz.user_id }}" class="qp-a-button-small border-2 border-blue-600 text-white font-bold drop-shadow-lg custom-outline">
|
||||
|
||||
<button type="submit" class=" text-sm py-1 text-white font-bold drop-shadow-lg custom-outline"> veröffentlicht von {{ quiz.user_id }}</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="{% static 'css/t-style.css' %}">
|
||||
<title>qivip</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div class="qp-question-container">
|
||||
<p class="text-gray-700 font-bold text-xl uppercase">Frage X</p>
|
||||
<img src="integral.png">
|
||||
<h1>Frage: {{ question.data.question }}</h1>
|
||||
<div>
|
||||
<div class="p-4">
|
||||
<p class="text-blue-500 text-xl">Verbleibende Zeit:</p>
|
||||
<p id="remaining_time" class="text-6xl">36</p>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<p class="text-blue-500 text-xl">7/14 Antworten</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="qp-answer-container-host" id="qp-answer-container-host">
|
||||
{% for option in question.data.options %}
|
||||
<div>
|
||||
<p>{{ option.value }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,19 +0,0 @@
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="{% static 'css/t-style.css' %}">
|
||||
<title>qivip</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="qp-answer-container" id="qp-answer-container">
|
||||
{% for option in question.data.options %}
|
||||
<div>
|
||||
<p>{{ option.value }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user