diff --git a/UWEFlix/__pycache__/forms.cpython-310.pyc b/UWEFlix/__pycache__/forms.cpython-310.pyc index 7d2b8dd23d19dede122396aa0092323147eb2923..275baa96faeb71ab99df915e7e209e5d3e4c682e 100644 Binary files a/UWEFlix/__pycache__/forms.cpython-310.pyc and b/UWEFlix/__pycache__/forms.cpython-310.pyc differ diff --git a/UWEFlix/__pycache__/models.cpython-310.pyc b/UWEFlix/__pycache__/models.cpython-310.pyc index 324fde43e74156df9fe7ae18e0509858eeaad2fd..a41f30d68ea2a1f14da1ee576341ac60c928efea 100644 Binary files a/UWEFlix/__pycache__/models.cpython-310.pyc and b/UWEFlix/__pycache__/models.cpython-310.pyc differ diff --git a/UWEFlix/__pycache__/urls.cpython-310.pyc b/UWEFlix/__pycache__/urls.cpython-310.pyc index 6cfc9aa41ddd2770aa51101ac76cb8f8304f3360..831c5e6fe67abe40bd2bf1cdd9b0b1ed1b36f08c 100644 Binary files a/UWEFlix/__pycache__/urls.cpython-310.pyc and b/UWEFlix/__pycache__/urls.cpython-310.pyc differ diff --git a/UWEFlix/__pycache__/views.cpython-310.pyc b/UWEFlix/__pycache__/views.cpython-310.pyc index b17f35df47ad4f5f5950f2189e2484c0a0b557a7..22f97ee8ed23183ed1148c30672854e1470f049d 100644 Binary files a/UWEFlix/__pycache__/views.cpython-310.pyc and b/UWEFlix/__pycache__/views.cpython-310.pyc differ diff --git a/UWEFlix/forms.py b/UWEFlix/forms.py index f819381dd55bb23e683acd5174837a9a78bf158e..9098fc9070d8b2dc0811d37f21391a1ce90e0f50 100644 --- a/UWEFlix/forms.py +++ b/UWEFlix/forms.py @@ -1,6 +1,6 @@ from django import forms from django.contrib.auth.models import User, Group -from .models import Account, User, Club, ClubRepresentative +from .models import Account, User, Club, ClubRepresentative, Screen, Cinema, Showing, Film from django.contrib.auth.forms import AuthenticationForm, UserCreationForm class AccountForm(forms.ModelForm): @@ -30,4 +30,32 @@ class RepresentativeRegistrationForm(forms.ModelForm): class ElevateUserForm(forms.ModelForm): user = forms.ModelChoiceField(queryset=User.objects.all()) - group = forms.ModelChoiceField(queryset=Group.objects.all()) \ No newline at end of file + group = forms.ModelChoiceField(queryset=Group.objects.all()) + + class Meta: + model = User + fields = ['user', 'group'] + +class ScreenForm(forms.ModelForm): + cinema = forms.ModelChoiceField(queryset=Cinema.objects.all()) + + class Meta: + model = Screen + fields = ['cinema', 'screen_number', 'seating_capacity'] + +class CinemaForm(forms.ModelForm): + class Meta: + model = Cinema + fields = ['name', 'location'] + +class ShowingForm(forms.ModelForm): + screen = forms.ModelChoiceField(queryset=Screen.objects.all()) + film = forms.ModelChoiceField(queryset=Film.objects.all()) + class Meta: + model = Showing + fields = ['screen', 'film', 'start_time'] + +class FilmForm(forms.ModelForm): + class Meta: + model = Film + fields = ['title', 'length', 'rating'] \ No newline at end of file diff --git a/UWEFlix/migrations/0004_seat.py b/UWEFlix/migrations/0004_seat.py new file mode 100644 index 0000000000000000000000000000000000000000..e748ff2dffdc15e5a83c4eb99a7bc8d9bda992c3 --- /dev/null +++ b/UWEFlix/migrations/0004_seat.py @@ -0,0 +1,21 @@ +# Generated by Django 4.1.4 on 2023-01-03 16:06 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('UWEFlix', '0003_cinema_film_screen_showing_cinemamanager_cinema'), + ] + + operations = [ + migrations.CreateModel( + name='Seat', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('screen', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='seats', to='UWEFlix.screen')), + ], + ), + ] diff --git a/UWEFlix/migrations/0005_alter_cinema_id_alter_film_id_alter_screen_id_and_more.py b/UWEFlix/migrations/0005_alter_cinema_id_alter_film_id_alter_screen_id_and_more.py new file mode 100644 index 0000000000000000000000000000000000000000..0f240068fbe699b507ec739424c822852bc249cc --- /dev/null +++ b/UWEFlix/migrations/0005_alter_cinema_id_alter_film_id_alter_screen_id_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 4.1.4 on 2023-01-03 23:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('UWEFlix', '0004_seat'), + ] + + operations = [ + migrations.AlterField( + model_name='cinema', + name='id', + field=models.AutoField(primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='film', + name='id', + field=models.AutoField(primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='screen', + name='id', + field=models.AutoField(primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='showing', + name='id', + field=models.AutoField(primary_key=True, serialize=False), + ), + ] diff --git a/UWEFlix/migrations/__pycache__/0004_seat.cpython-310.pyc b/UWEFlix/migrations/__pycache__/0004_seat.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cc840dbb21de65aca0bf9ca5d4b74e0f82e81c1b Binary files /dev/null and b/UWEFlix/migrations/__pycache__/0004_seat.cpython-310.pyc differ diff --git a/UWEFlix/migrations/__pycache__/0005_alter_cinema_id_alter_film_id_alter_screen_id_and_more.cpython-310.pyc b/UWEFlix/migrations/__pycache__/0005_alter_cinema_id_alter_film_id_alter_screen_id_and_more.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6fdc9d2d215e541b6340a34e32456f7ac871b8f3 Binary files /dev/null and b/UWEFlix/migrations/__pycache__/0005_alter_cinema_id_alter_film_id_alter_screen_id_and_more.cpython-310.pyc differ diff --git a/UWEFlix/models.py b/UWEFlix/models.py index 8efe4a78094d9f37a9f2b0536ae50ad4275c72fd..026825009077962f4dc9b0606bd715c9ea481d4f 100644 --- a/UWEFlix/models.py +++ b/UWEFlix/models.py @@ -80,20 +80,31 @@ class Account(models.Model): end_of_month_statements = models.TextField() class Cinema(models.Model): + id = models.AutoField(primary_key=True) name = models.CharField(max_length=255) location = models.CharField(max_length=255) class Film(models.Model): + id = models.AutoField(primary_key=True) title = models.CharField(max_length=255) length = models.PositiveIntegerField() rating = models.PositiveSmallIntegerField() class Screen(models.Model): + id = models.AutoField(primary_key=True) cinema = models.ForeignKey(Cinema, on_delete=models.CASCADE, related_name='screens') screen_number = models.PositiveSmallIntegerField() seating_capacity = models.PositiveIntegerField() class Showing(models.Model): + id = models.AutoField(primary_key=True) film = models.ForeignKey(Film, on_delete=models.CASCADE, related_name='showings') screen = models.ForeignKey(Screen, on_delete=models.CASCADE, related_name='showings') - start_time = models.DateTimeField() \ No newline at end of file + start_time = models.DateTimeField() + + + + +class Seat(models.Model): + screen = models.ForeignKey(Screen, on_delete=models.CASCADE, related_name="seats") + diff --git a/UWEFlix/templates/base.html b/UWEFlix/templates/base.html index 95190c26a14cda0c9d9633f48bcaf7182259e8ef..bf31cc42ab8416bddaf8d81a2aade0c89a7d8b3b 100644 --- a/UWEFlix/templates/base.html +++ b/UWEFlix/templates/base.html @@ -22,14 +22,19 @@ <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item active"> - <a class="nav-link" href="#">Home</a> + <a class="nav-link" href="{% url 'index' %}">Home</a> </li> <li class="nav-item"> - <a class="nav-link" href="#">About</a> + <a class="nav-link" href="#">Buy Ticket</a> </li> <li class="nav-item"> - <a class="nav-link" href="#">Contact</a> + <a class="nav-link" href="#">View Tickets</a> </li> + {% if request.user.is_authenticated %} + <li class="nav-item"> + <a class = "nav-link" href="{% url 'view_details' %}">View My Details</a> + </li> + {% endif %} </ul> </div> </nav> diff --git a/UWEFlix/templates/create_screen.html b/UWEFlix/templates/create_screen.html new file mode 100644 index 0000000000000000000000000000000000000000..5b1097ce3a4a4c2b2472ca7ea926b5dff14a0770 --- /dev/null +++ b/UWEFlix/templates/create_screen.html @@ -0,0 +1,29 @@ +{% extends 'base.html' %} + +{% block content %} + +<div class="container mt-4"> + <h1>Create Screen</h1> + <form method="post" action="{% url 'create_screen' %}"> + {% csrf_token %} + <div class="form-group"> + <label for="screen_number">Screen Number</label> + <input type="number" class="form-control" id="screen_number" name="screen_number" required> + </div> + <div class="form-group"> + <label for="seating_capacity">Seating Capacity</label> + <input type="number" class="form-control" id="seating_capacity" name="seating_capacity" required> + </div> + <div class="form-group"> + <label for="cinema">Cinema</label> + <select class="form-control" id="cinema" name="cinema"> + {% for cinema in cinemas %} + <option value="{{ cinema.id }}">{{ cinema.name }}</option> + {% endfor %} + </select> + </div> + <button type="submit" class="btn btn-primary">Create Screen</button> + </form> +</div> + +{% endblock %} \ No newline at end of file diff --git a/UWEFlix/templates/create_showing.html b/UWEFlix/templates/create_showing.html new file mode 100644 index 0000000000000000000000000000000000000000..afea2eabe2acee7b643309f053e9811ed73a8d76 --- /dev/null +++ b/UWEFlix/templates/create_showing.html @@ -0,0 +1,30 @@ +{% extends 'base.html' %} + +{% block content %} + +<div class="container mt-4"> + <h1>Create Showing</h1> + <form method="post" action="{% url 'create_showing' screen.pk %}"> + {% csrf_token %} + <div class="form-group"> + <label for="film">Film</label> + <select class="form-control" id="film" name="film"> + {% for film in films %} + <option value="{{ film.id }}">{{ film.title }}</option> + {% endfor %} + </select> + </div> + <div class="form-group"> + <label for="screen">Screen</label> + <select class="form-control" id="screen" name="screen"> + <option value="{{ screen.id }}">{{ screen.cinema.name }} - Screen {{ screen.screen_number }}</option> + </select> + </div> + <div class="form-group"> + <label for="start_time">Start Time</label> + <input type="datetime-local" class="form-control" id="start_time" name="start_time" required> + </div> + <button type="submit" class="btn btn-primary">Create Showing</button> + </form> +</div> +{% endblock %} \ No newline at end of file diff --git a/UWEFlix/templates/index.html b/UWEFlix/templates/index.html index 35837f0f690cd1efc93996d735bf13f693e0ae10..198e1ce1179f7fb81ff714d7f56c4f54e917f2e3 100644 --- a/UWEFlix/templates/index.html +++ b/UWEFlix/templates/index.html @@ -5,40 +5,16 @@ <div class="container mt-4"> <h1>Index</h1> {% if request.user.is_authenticated %} - {% if request.user.is_staff or request.user.is_superuser %} - <p>Welcome, {{ request.user.first_name }}! As an administrator, you have access to the following pages:</p> - <ul> - <li><a href="{% url 'create_account' %}">Create Account</a></li> - <li><a href="{% url 'representative_registration' %}">Representative Registration</a></li> - <li><a href="{% url 'create_club' %}">Club Registration</a></li> - <li><a href="{% url 'elevate_user' %}" class="btn btn-secondary mt-2">Elevate User</a></li> - </ul> - {% elif request.user.groups.filter(name='Cinema Manager').exists %} - <p>Welcome, {{ request.user.first_name }}! As a Cinema Manager, you have access to the following pages:</p> - <ul> - <li><a href="{% url 'create_account' %}">Create Account</a></li> - <li><a href="{% url 'representative_registration' %}">Representative Registration</a></li> - <li><a href="{% url 'create_club' %}">Club Registration</a></li> - </ul> - {% elif request.user.user_type == 'CR' %} - <p>Welcome, {{ request.user.first_name }}! As a club representative, you have access to the following pages:</p> - <ul> - <li><a href="{% url 'create_club' %}">Create Club</a></li> - </ul> - {% else %} - <p>Welcome, {{ request.user.first_name }}! You have access to the following pages:</p> - <ul> - <li><a href="{% url 'login' %}">Login</a></li> - <li><a href="{% url 'register' %}">Register</a></li> - </ul> - {% endif %} + <p>Welcome, {{ request.user.first_name }}! You have access to the following pages:</p> {% else %} <p>Welcome! You have access to the following pages:</p> - <ul> - <li><a href="{% url 'login' %}">Login</a></li> - <li><a href="{% url 'register' %}">Register</a></li> - </ul> {% endif %} + <ul> + <li><a href="{% url 'create_account' %}">Create Account</a></li> + <li><a href="{% url 'representative_registration' %}">Representative Registration</a></li> + <li><a href="{% url 'create_club' %}">Club Registration</a></li> + <li><a href="{% url 'elevate_user' %}" class="btn btn-secondary mt-2">Elevate User</a></li> + </ul> </div> {% endblock %} \ No newline at end of file diff --git a/UWEFlix/templates/manage_screens.html b/UWEFlix/templates/manage_screens.html new file mode 100644 index 0000000000000000000000000000000000000000..b7e3032eddcd0dcf47d8d9e08ccdc51cd5b653f9 --- /dev/null +++ b/UWEFlix/templates/manage_screens.html @@ -0,0 +1,37 @@ +{% extends 'base.html' %} + +{% block content %} + +<div class="container mt-4"> + <h1>Manage Screens</h1> + {% if screens %} + {% for screen in screens %} + <div class="card mb-3"> + <div class="card-body"> + <h5 class="card-title">Screen {{ screen.screen_number }}</h5> + <p class="card-text">Cinema: {{ screen.cinema.name }}</p> + <p class="card-text">Seating Capacity: {{ screen.seating_capacity }}</p> + <a href="{% url 'update_screen' pk=screen.pk %}" class="btn btn-primary">Update</a> + <a href="{% url 'delete_screen' pk=screen.pk %}" class="btn btn-danger">Delete</a> + <a href="{% url 'create_showing' pk=screen.pk %}" class="btn btn-success mt-2">Create Showing</a> + {% if screen.showings %} + <h6 class="mt-3">Showings:</h6> + <ul> + {% for showing in showings %} + {% if showing.screen.pk == screen.pk %} + <li>{{ showing.film.title }} - {{ showing.start_time|date:'g:i A' }}</li> + {% endif %} + {% endfor %} + </ul> + {% else %} + <p class="mt-3">No showings for this screen.</p> + {% endif %} + </div> + </div> + {% endfor %} + {% else %} + <p>No screens to display.</p> + {% endif %} + <a href="{% url 'create_screen' %}" class="btn btn-success mt-2">Create Screen</a> +</div> +{% endblock %} \ No newline at end of file diff --git a/UWEFlix/templates/update_screen.html b/UWEFlix/templates/update_screen.html new file mode 100644 index 0000000000000000000000000000000000000000..3813f8855be0df549cac2eb597e7ed65e48eb95f --- /dev/null +++ b/UWEFlix/templates/update_screen.html @@ -0,0 +1,19 @@ +{% extends 'base.html' %} + +{% block content %} + +<div class="container mt-4"> + <h1>Update Screen</h1> + <form method="post" action="{% url 'update_screen' screen.id %}"> + {% csrf_token %} + {% for field in form %} + <div class="form-group"> + {{ field.label_tag }} + {{ field }} + </div> + {% endfor %} + <button type="submit" class="btn btn-primary">Update Screen</button> + </form> +</div> + +{% endblock %} \ No newline at end of file diff --git a/UWEFlix/templates/view_details.html b/UWEFlix/templates/view_details.html new file mode 100644 index 0000000000000000000000000000000000000000..a33b810e41759860b72a4082eef8cb049b0f1340 --- /dev/null +++ b/UWEFlix/templates/view_details.html @@ -0,0 +1,13 @@ +{% extends 'base.html' %} + +{% block content %} + +<div class="container mt-4"> + <h1>My Details</h1> + <p>Username: {{ user.username }}</p> + <p>First Name: {{ user.first_name }}</p> + <p>Last Name: {{ user.last_name }}</p> + <p>Email: {{ user.email }}</p> +</div> + +{% endblock %} \ No newline at end of file diff --git a/UWEFlix/urls.py b/UWEFlix/urls.py index c72a35eb037c7892c7907d99ff0058268fef9b1d..e3389e0cb126e6c47d9cce2774c306d53975e359 100644 --- a/UWEFlix/urls.py +++ b/UWEFlix/urls.py @@ -11,4 +11,12 @@ urlpatterns = [ path('register/', views.register_view, name='register'), path('create_club/', views.create_club, name='create_club'), path('representative_registration/', views.representative_registration, name='representative_registration'), + path('elevate_user', views.elevate_user_view, name='elevate_user'), + path('view_details/', views.view_my_details, name='view_details'), + path('manage_screens/', views.screen_list, name='manage_screens'), + path('manage_screens/create_screen/', views.screen_create, name='create_screen'), + path('manage_screens/update_screen/<int:pk>/', views.screen_update, name='update_screen'), + path('manage_screens/delete_screen/<int:pk>/', views.screen_delete, name='delete_screen'), + path('manage_screens/screen_list/', views.screen_list, name='screen_list'), + path('manage_screens/showings/create_showing/<int:pk>/', views.showing_create, name='create_showing') ] diff --git a/UWEFlix/views.py b/UWEFlix/views.py index c60d8a233de0ac1b075b42cc8bc314e6870e13be..bbda8a29a91d2d78f99bfac350dbd4a2dbd14dd2 100644 --- a/UWEFlix/views.py +++ b/UWEFlix/views.py @@ -1,8 +1,8 @@ -from django.shortcuts import render, redirect, HttpResponseRedirect +from django.shortcuts import render, redirect, HttpResponseRedirect, get_object_or_404 from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required -from .forms import AccountForm, UserRegistrationForm, ClubForm, RepresentativeRegistrationForm, ElevateUserForm -from .models import Account, User, ClubRepresentative, Club +from .forms import AccountForm, UserRegistrationForm, ClubForm, RepresentativeRegistrationForm, ElevateUserForm, ScreenForm, ShowingForm +from .models import Account, User, ClubRepresentative, Club, Screen, Cinema, Film, Showing from django.http import JsonResponse @@ -87,12 +87,87 @@ def representative_registration(request): def elevate_user_view(request): - if request.method== 'POST': + if request.method == 'POST': form = ElevateUserForm(request.POST) if form.is_valid(): - form.save(commit=True) - return redirect('/index/') - - else: - form = ElevateUserForm() - return render(request, 'elevate_user.html', {'form': form}) \ No newline at end of file + # Form is valid, process the data and return a response + # ... + return redirect('index') + else: + form = ElevateUserForm() + return render(request, 'elevate_user.html', {'form': form}) + + +def view_my_details(request): + if request.method == 'GET': + # Get the current logged-in user + user = request.user + # Render the template with the user's details + return render(request, 'view_details.html', {'user': user}) + + +### SCREEN MANAGEMENT ### +def screen_list(request): + screens = Screen.objects.all() + showings = Showing.objects.all() + return render(request, 'manage_screens.html', {'screens': screens, 'showings': showings}) + +def screen_create(request): + # if request.method == 'POST': + # form = ScreenForm(request.POST) + # if form.is_valid(): + # # Check if the user is a cinema manager + # if request.user.groups.filter(name='Cinema Manager').exists(): + # # Check if the cinema the user manages matches the cinema associated with the screen + # if request.user.cinema == form.cleaned_data['cinema']: + # form.save() + # return redirect('manage_screens') + # else: + # # Return an error message or redirect the user to a different page + # pass + # else: + # # Return an error message or redirect the user to a different page + # pass + # else: + # form = ScreenForm() + # return render(request, 'create_screen.html', {'form': form}) + + if request.method == 'POST': + form = ScreenForm(request.POST) + if form.is_valid(): + # Check if the user is a cinema manager + #if request.user.groups.filter(name='Cinema Manager').exists(): + # Check if the cinema the user manages matches the cinema associated with the screen + #if request.user.cinema == form.cleaned_data['cinema']: + form.save() + return redirect('manage_screens') + else: + form = ScreenForm() + return render(request, 'create_screen.html', {'form': form, 'cinemas': Cinema.objects.all()}) + +def screen_update(request, pk): + screen = get_object_or_404(Screen, pk=pk) + if request.method == 'POST': + form = ScreenForm(request.POST, instance=screen) + if form.is_valid(): + form.save() + return redirect('screen_list') + else: + form = ScreenForm(instance=screen) + return render(request, 'update_screen.html', {'form': form, 'screen': screen}) + +def screen_delete(request, pk): + screen = get_object_or_404(Screen, pk=pk) + screen.delete() + return redirect('screen_list') + +def showing_create(request, pk): + screen = get_object_or_404(Screen, pk=pk) + if request.method == 'POST': + form = ShowingForm(request.POST) + if form.is_valid(): + form.save() + return redirect('manage_screens') + else: + form = ShowingForm() + return render(request, 'create_showing.html', {'form': form, 'films': Film.objects.all(), 'screen': screen}) \ No newline at end of file diff --git a/db.sqlite3 b/db.sqlite3 index 26aff06e47ad63b3887aa7f7559f41d03c5cbb93..c98ac66b7484603760582aaa93f735be51a04626 100644 Binary files a/db.sqlite3 and b/db.sqlite3 differ