Skip to content

Commit

Permalink
Merge branch 'dev' into users/admin-user-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewM131 authored Dec 5, 2023
2 parents 4804543 + 99734eb commit 90fc6e7
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 25 deletions.
26 changes: 25 additions & 1 deletion src/chigame/games/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django import forms
from django.core.validators import MaxValueValidator, MinValueValidator

from .models import Game, Lobby
from .models import Game, Lobby, Review


class GameForm(forms.ModelForm):
Expand All @@ -25,3 +26,26 @@ class Meta:
model = Lobby
fields = ["name", "game", "game_mod_status", "min_players", "max_players", "time_constraint"]
widgets = {"name": forms.TextInput}


class ReviewForm(forms.ModelForm):
class Meta:
model = Review
fields = ["title", "review", "rating", "is_public"]

title = forms.CharField(widget=forms.TextInput(attrs={"placeholder": "Title (optional)"}), required=False)
review = forms.CharField(widget=forms.Textarea(attrs={"placeholder": "Your review"}), required=False)
rating = forms.DecimalField(
widget=forms.NumberInput(attrs={"placeholder": "Rating (1-5)"}),
validators=[MinValueValidator(1), MaxValueValidator(5)],
required=False,
)
is_public = forms.BooleanField(initial=True, required=False)

def clean(self):
cleaned_data = super().clean()
review = cleaned_data.get("review")
rating = cleaned_data.get("rating")

if not review and rating is None:
raise forms.ValidationError("At least one of 'review' or 'rating' must be provided.")
17 changes: 17 additions & 0 deletions src/chigame/games/migrations/0021_alter_tournament_matches.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.4 on 2023-12-05 02:14

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("games", "0020_merge_20231204_1517"),
]

operations = [
migrations.AlterField(
model_name="tournament",
name="matches",
field=models.ManyToManyField(blank=True, related_name="tournament", to="games.match"),
),
]
1 change: 1 addition & 0 deletions src/chigame/games/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
path("<int:pk>/", views.GameDetailView.as_view(), name="game-detail"),
path("bgg_search_by_name/", views.bgg_search_by_name, name="bgg_search_by_name"),
path("search/", views.search_results, name="game-search-results"),
path("<int:pk>/reviews/", views.ReviewListView.as_view(), name="game-review-list"),
# tournaments
path("tournaments/", views.TournamentListView.as_view(), name="tournament-list"),
path("tournaments/<int:pk>/", views.TournamentDetailView.as_view(), name="tournament-detail"),
Expand Down
50 changes: 46 additions & 4 deletions src/chigame/games/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@
from django.core.paginator import Paginator
from django.db.models import Q
from django.db.models.functions import Lower
from django.http import HttpResponseForbidden, JsonResponse
from django.http import HttpResponseForbidden, HttpResponseRedirect, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render, reverse
from django.urls import reverse_lazy
from django.utils import timezone
from django.utils.decorators import method_decorator
from django.views.generic import CreateView, DeleteView, DetailView, ListView, UpdateView
from django.views.generic.edit import FormMixin

from .filters import LobbyFilter
from .forms import GameForm, LobbyForm
from .models import Chat, Game, Lobby, Match, Player, Tournament
from .forms import GameForm, LobbyForm, ReviewForm
from .models import Chat, Game, Lobby, Match, Player, Review, Tournament
from .tables import LobbyTable


Expand All @@ -42,10 +43,34 @@ def get_queryset(self):
return queryset


class GameDetailView(DetailView):
class GameDetailView(LoginRequiredMixin, FormMixin, DetailView):
model = Game
template_name = "games/game_detail.html"
context_object_name = "game"
form_class = ReviewForm

def get_success_url(self):
return reverse("game-detail", kwargs={"pk": self.object.pk})

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["form"] = self.get_form()
context["reviews"] = Review.objects.filter(game=self.object)
return context

def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)

def form_valid(self, form):
form.instance.user = self.request.user
form.instance.game = self.object
form.save()
return HttpResponseRedirect(self.get_success_url())


class GameCreateView(UserPassesTestMixin, CreateView):
Expand Down Expand Up @@ -673,3 +698,20 @@ def TournamentChatDetailView(request, pk):
except ObjectDoesNotExist:
messages.error(request, "This tournament does not have a chat yet.")
return redirect(reverse_lazy("tournament-detail", kwargs={"pk": pk}))


class ReviewListView(ListView):
model = Review
template_name = "games/game_reviews.html"
context_object_name = "reviews"

def get_queryset(self):
game_pk = self.kwargs["pk"]
game = get_object_or_404(Game, pk=game_pk)
return Review.objects.filter(game=game, is_public=True)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
game_pk = self.kwargs["pk"]
context["game"] = get_object_or_404(Game, pk=game_pk)
return context
25 changes: 25 additions & 0 deletions src/chigame/users/migrations/0005_alter_user_username.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.2.4 on 2023-12-04 22:15

import chigame.users.models
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("users", "0004_user_username"),
]

operations = [
migrations.AlterField(
model_name="user",
name="username",
field=models.CharField(
blank=True,
max_length=255,
null=True,
unique=True,
validators=[chigame.users.models.validate_username],
verbose_name="username",
),
),
]
59 changes: 40 additions & 19 deletions src/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,41 @@
<a id="log-in-link" class="nav-link" href="{% url 'account_login' %}">{% translate "Sign In" %}</a>
</li>
{% endif %}
<li class="nav-item d-flex align-items-center">
<li class="nav-item">
<!-- Dynamically update search bar landing page depending on query_type-->
<form id="search-bar" action="{% url 'game-search-results' %}" method="get">
<select id="query-type" name="query_type">
<option value="games">Games</option>
<option value="users">Users</option>
<option value="forums">Forums</option>
<!-- Add more options here -->
</select>
<!-- Name must remain as "q" as django-machina expects that name -->
<div class="d-inline-flex align-items-center">
<input id="query-input" name="q" type="text" placeholder="Search..." />
<form id="search-bar"
action="{% url 'game-search-results' %}"
method="get"
class="d-flex align-items-center">
<div>
{% url 'forum:index' as forum_url %}
{% url 'forum_search:search' as forum_search_url %}
{% url 'games:index' as games_url %}
{% url 'game-search-results' as game_search_url %}
{% url 'users:user-search-results' as users_search_url %}
<select id="query-type" name="query_type" class="form-select">
<option value="games"
{% if request.path == games_url or request.path == games_search_url %}selected{% endif %}>
Games
</option>
<option value="users"
{% if request.path == users_search_url %}selected{% endif %}>Users</option>
<option value="forums"
{% if request.path == forum_url or request.path == forum_search_url %}selected{% endif %}>
Forums
</option>
<!-- Add more options here -->
</select>
</div>
<div>
<!-- Name must remain as "q" as django-machina expects that name -->
<input id="query-input"
name="q"
type="text"
placeholder="Search..."
class="form-control me-2" />
</div>
<div>
<button id="advanced-search-button"
class="btn btn-large btn-primary ms-2 d-none"
type="button">{% trans "Advanced Search" %}</button>
Expand Down Expand Up @@ -212,11 +235,11 @@
});

// if the query type changes, update the landing page and autocomplete options
query_type.addEventListener("change", function() {
function updateFormAction() {
if (query_type.value === "games") {
search_bar.action = "{% url 'game-search-results' %}";

{% get_games as games %} // fetch game names for autocomplete
{% get_games as games %} // fetch game names for autocomplete
var game_names = [
{% for game in games %}
{
Expand Down Expand Up @@ -256,13 +279,11 @@
source: [] // placeholder; replace with list of forums
});
}
advancedSearchButton.classList.toggle('d-none', query_type.value !== "forums"); // hide advanced search button if not searching forums
}

if (query_type.value === "forums") {
advancedSearchButton.classList.remove('d-none'); // Show the advanced search button
} else {
advancedSearchButton.classList.add('d-none'); // Hide the advanced search button
}
});
updateFormAction();
query_type.addEventListener("change", updateFormAction);

advancedSearchButton.addEventListener("click", function(event) {
query_input.value = ''; // Clear the input field
Expand Down
11 changes: 10 additions & 1 deletion src/templates/games/game_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,16 @@ <h3 id="playtime-description">Playtime</h3>
</p>
{% endif %}
<h3 id="rule-description">Rules</h3>
<p>{{ game.rules }}</p>
<div class="mb-4">
<p>{{ game.rules }}</p>
<h3 id="new-review">Write a Review</h3>
<form method="post" action="{% url 'game-detail' pk=game.pk %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">Submit Review</button>
</form>
</div>
<a href="{% url 'game-review-list' pk=game.pk %}">See All Reviews for {{ game.name }}</a>
</div>
</div>
</div>
Expand Down
27 changes: 27 additions & 0 deletions src/templates/games/game_reviews.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% extends "base.html" %}

{% block title %}
Reviews for {{ game.name }}
{% endblock title %}
{% block content %}
<h1>Reviews for {{ game.name }}</h1>
{% if reviews %}
<ul>
{% for review in reviews %}
<li>
{% if review.title %}<h3>{{ review.title }}</h3>{% endif %}
<p>
{{ review.user }}
{% if review.rating is not None %}rated it {{ review.rating }}/5.00{% endif %}
:
</p>
<p>{{ review.review }}</p>
<hr />
</li>
{% endfor %}
</ul>
{% else %}
<p>No reviews available for {{ game.name }}.</p>
{% endif %}
<a href="{% url 'game-list' %}">Back to Games List</a>
{% endblock content %}

0 comments on commit 90fc6e7

Please sign in to comment.