diff --git a/.github/workflows/build_and_deploy.yaml b/.github/workflows/build_and_deploy.yaml
index 3faea0f04..b7507cd94 100644
--- a/.github/workflows/build_and_deploy.yaml
+++ b/.github/workflows/build_and_deploy.yaml
@@ -44,6 +44,10 @@ jobs:
working-directory: frontend
run: npm install
+ - name: Print npm log
+ if: failure()
+ run: cat /home/runner/.npm/_logs/*.log
+
- name: Build Frontend
working-directory: frontend
run: npm run build
diff --git a/.gitignore b/.gitignore
index 8e4150bdb..2c65e9a2b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,7 @@
# dependencies
-*/node_modules
+node_modules
*/.pnp
*.pnp.js
@@ -44,4 +44,13 @@
*yarn-debug.log*
*yarn-error.log*
-node_modules
\ No newline at end of file
+# Jamshidbek
+to-do.txt
+jsonuser.json
+
+# backend/authentication
+backend/authentication/images/*
+
+# media
+media
+node_modules
diff --git a/backend.sh b/backend.sh
new file mode 100755
index 000000000..c33b44620
--- /dev/null
+++ b/backend.sh
@@ -0,0 +1,2 @@
+cd backend && source venv/bin/activate
+python manage.py makemigrations && python manage.py migrate
\ No newline at end of file
diff --git a/backend/authentication/admin.py b/backend/authentication/admin.py
index 8c38f3f3d..00d4f380f 100644
--- a/backend/authentication/admin.py
+++ b/backend/authentication/admin.py
@@ -1,3 +1,6 @@
from django.contrib import admin
+from .models import User
# Register your models here.
+
+admin.site.register(User)
\ No newline at end of file
diff --git a/backend/authentication/migrations/0001_initial.py b/backend/authentication/migrations/0001_initial.py
index 97c536389..946880240 100644
--- a/backend/authentication/migrations/0001_initial.py
+++ b/backend/authentication/migrations/0001_initial.py
@@ -1,5 +1,8 @@
-# Generated by Django 5.0 on 2023-12-10 07:48
+# Generated by Django 5.0 on 2023-12-19 09:26
+import django.contrib.auth.models
+import django.contrib.auth.validators
+import django.utils.timezone
from django.db import migrations, models
@@ -8,6 +11,7 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
+ ('auth', '0001_initial'),
]
operations = [
@@ -15,10 +19,26 @@ class Migration(migrations.Migration):
name='User',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('username', models.CharField(max_length=255)),
- ('display_name', models.CharField(max_length=255)),
- ('email', models.EmailField(max_length=254)),
- ('picture', models.URLField()),
+ ('password', models.CharField(max_length=128, verbose_name='password')),
+ ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
+ ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
+ ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
+ ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
+ ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
+ ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
+ ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
+ ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
+ ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
+ ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
+ ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
+ ],
+ options={
+ 'verbose_name': 'user',
+ 'verbose_name_plural': 'users',
+ 'abstract': False,
+ },
+ managers=[
+ ('objects', django.contrib.auth.models.UserManager()),
],
),
]
diff --git a/backend/authentication/migrations/0002_alter_user_id.py b/backend/authentication/migrations/0002_alter_user_id.py
deleted file mode 100644
index 9169e7b8c..000000000
--- a/backend/authentication/migrations/0002_alter_user_id.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 5.0 on 2023-12-13 10:59
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('authentication', '0001_initial'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='user',
- name='id',
- field=models.DecimalField(decimal_places=0, max_digits=10, primary_key=True, serialize=False, unique=True),
- ),
- ]
diff --git a/backend/authentication/migrations/0002_user_losses_user_total_matches_user_wins.py b/backend/authentication/migrations/0002_user_losses_user_total_matches_user_wins.py
new file mode 100644
index 000000000..87d84355a
--- /dev/null
+++ b/backend/authentication/migrations/0002_user_losses_user_total_matches_user_wins.py
@@ -0,0 +1,28 @@
+# Generated by Django 5.0 on 2023-12-20 09:36
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('authentication', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='user',
+ name='losses',
+ field=models.PositiveIntegerField(default=0),
+ ),
+ migrations.AddField(
+ model_name='user',
+ name='total_matches',
+ field=models.PositiveIntegerField(default=0),
+ ),
+ migrations.AddField(
+ model_name='user',
+ name='wins',
+ field=models.PositiveIntegerField(default=0),
+ ),
+ ]
diff --git a/backend/authentication/migrations/0003_delete_user.py b/backend/authentication/migrations/0003_delete_user.py
deleted file mode 100644
index 1ed913791..000000000
--- a/backend/authentication/migrations/0003_delete_user.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 5.0 on 2023-12-15 09:23
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('authentication', '0002_alter_user_id'),
- # ('leaderboard', '0003_delete_friendship'),
- ]
-
- operations = [
- migrations.DeleteModel(
- name='User',
- ),
- ]
diff --git a/backend/authentication/migrations/0003_user_picture.py b/backend/authentication/migrations/0003_user_picture.py
new file mode 100644
index 000000000..89dadbd89
--- /dev/null
+++ b/backend/authentication/migrations/0003_user_picture.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0 on 2023-12-20 10:19
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('authentication', '0002_user_losses_user_total_matches_user_wins'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='user',
+ name='picture',
+ field=models.ImageField(blank=True, default='default_profile_picture.PNG', null=True, upload_to='authentication/images/'),
+ ),
+ ]
diff --git a/backend/authentication/migrations/0004_rename_picture_user_profile_picture.py b/backend/authentication/migrations/0004_rename_picture_user_profile_picture.py
new file mode 100644
index 000000000..25d166d19
--- /dev/null
+++ b/backend/authentication/migrations/0004_rename_picture_user_profile_picture.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0 on 2023-12-20 10:22
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('authentication', '0003_user_picture'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='user',
+ old_name='picture',
+ new_name='profile_picture',
+ ),
+ ]
diff --git a/backend/authentication/migrations/0005_user_title.py b/backend/authentication/migrations/0005_user_title.py
new file mode 100644
index 000000000..9d72bc258
--- /dev/null
+++ b/backend/authentication/migrations/0005_user_title.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0 on 2023-12-21 10:00
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('authentication', '0004_rename_picture_user_profile_picture'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='user',
+ name='title',
+ field=models.CharField(blank=True, max_length=100, null=True),
+ ),
+ ]
diff --git a/backend/authentication/migrations/0006_alter_user_profile_picture.py b/backend/authentication/migrations/0006_alter_user_profile_picture.py
new file mode 100644
index 000000000..5c3def6c2
--- /dev/null
+++ b/backend/authentication/migrations/0006_alter_user_profile_picture.py
@@ -0,0 +1,19 @@
+# Generated by Django 5.0 on 2023-12-21 12:39
+
+import authentication.models
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('authentication', '0005_user_title'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='user',
+ name='profile_picture',
+ field=models.ImageField(blank=True, default='default_profile_picture.PNG', null=True, upload_to=authentication.models.user_profile_picture_path),
+ ),
+ ]
diff --git a/backend/authentication/migrations/0007_friendrequest.py b/backend/authentication/migrations/0007_friendrequest.py
new file mode 100644
index 000000000..2a4e89333
--- /dev/null
+++ b/backend/authentication/migrations/0007_friendrequest.py
@@ -0,0 +1,25 @@
+# Generated by Django 5.0 on 2023-12-22 13:23
+
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('authentication', '0006_alter_user_profile_picture'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='FriendRequest',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('status', models.CharField(choices=[('pending', 'Pending'), ('accepted', 'Accepted'), ('rejected', 'Rejected')], default='pending', max_length=10)),
+ ('timestamp', models.DateTimeField(auto_now_add=True)),
+ ('from_user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='friend_requests_sent', to=settings.AUTH_USER_MODEL)),
+ ('to_user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='friend_requests_received', to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ ]
diff --git a/backend/authentication/models.py b/backend/authentication/models.py
index 71a836239..0ef6b74a0 100644
--- a/backend/authentication/models.py
+++ b/backend/authentication/models.py
@@ -1,3 +1,44 @@
from django.db import models
-
+from django.contrib.auth.models import AbstractUser
+from .utils import user_profile_picture_path
# Create your models here.
+
+class User(AbstractUser):
+
+ profile_picture = models.ImageField(upload_to=user_profile_picture_path, null=True, blank=True, default='default_profile_picture.PNG')
+ total_matches = models.PositiveIntegerField(default=0)
+ wins = models.PositiveIntegerField(default=0)
+ losses = models.PositiveIntegerField(default=0)
+ title = models.CharField(max_length=100, null=True, blank=True)
+
+ def get_friends(self) -> list:
+ accepted_requests = FriendRequest.objects.filter(
+ models.Q(from_user=self, status='accepted') | models.Q(to_user=self, status='accepted')
+ )
+ friends = [request.to_user if request.from_user == self else request.from_user for request in accepted_requests]
+ return friends
+
+ def get_received_friend_requests(self) -> list:
+ received_requests = FriendRequest.objects.filter(to_user=self, status='pending')
+ users = [request.from_user for request in received_requests]
+ return users
+
+
+
+ def __str__(self) -> str:
+ return "Custom User: " + super().__str__() + ' . Total matches: ' + str(self.total_matches) + ' . Wins: ' + str(self.wins) + ' . Losses: ' + str(self.losses)
+
+class FriendRequest(models.Model):
+ STATUS_CHOICES = (
+ ('pending', 'Pending'),
+ ('accepted', 'Accepted'),
+ ('rejected', 'Rejected'),
+ )
+
+ from_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='friend_requests_sent')
+ to_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='friend_requests_received')
+ status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='pending')
+ timestamp = models.DateTimeField(auto_now_add=True)
+
+ def __str__(self):
+ return f"{self.from_user} to {self.to_user} ({self.status})"
\ No newline at end of file
diff --git a/backend/authentication/templates/base.html b/backend/authentication/templates/base.html
deleted file mode 100644
index e69de29bb..000000000
diff --git a/backend/authentication/templates/home.html b/backend/authentication/templates/home.html
index 077a65aeb..2d075080c 100644
--- a/backend/authentication/templates/home.html
+++ b/backend/authentication/templates/home.html
@@ -2,32 +2,45 @@
-
-
- Welcome to Ping Pong World
-
-
+
+
+ Welcome to Ping Pong World
+
+
-
-
Ping Pong Home Page
-
The Ultimate Ping Pong Experience!
+
+
Ping Pong Home Page
+
The Ultimate Ping Pong Experience!
-
-
+
+
+
+
Users List
+
+
+
+
+
diff --git a/backend/authentication/templates/login.html b/backend/authentication/templates/login.html
index ad6be61d4..c9a99b33e 100644
--- a/backend/authentication/templates/login.html
+++ b/backend/authentication/templates/login.html
@@ -16,15 +16,19 @@
diff --git a/backend/authentication/templates/test.html b/backend/authentication/templates/test.html
new file mode 100644
index 000000000..8a32a3b1d
--- /dev/null
+++ b/backend/authentication/templates/test.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ Test Page
+
+
+
+
+
+
Test Page
+
+
+ {% if user %}
+ User created or already exists. User: {{ user.username }}
+ {% else %}
+ An error occurred while creating the user.
+ {% endif %}
+
+
+
+
+
+
diff --git a/backend/authentication/templates/users_list.html b/backend/authentication/templates/users_list.html
new file mode 100644
index 000000000..80a6ba13d
--- /dev/null
+++ b/backend/authentication/templates/users_list.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ User List
+
+
+
+
+
+
+ {% for user in users %}
+
+
{{ user.username }}
+
+
{{ user.email }}
+
Total Matches: {{ user.total_matches }}
+
Wins: {{ user.wins }}
+
Losses: {{ user.losses }}
+
Title: {{ user.title }}
+
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/backend/authentication/urls.py b/backend/authentication/urls.py
index 9efbd69d4..0f495d298 100644
--- a/backend/authentication/urls.py
+++ b/backend/authentication/urls.py
@@ -1,7 +1,9 @@
from django.urls import path
from . import views
+
# Create different uri roots to connect them to a view
+
urlpatterns = [
path("", views.home, name="home"),
path("login/", views.my_login, name="login"),
@@ -9,5 +11,8 @@
path("auth/", views.auth, name="auth"),
path("auth_callback/", views.auth_callback, name="auth_callback"),
path("register/", views.register, name="register"),
-]
+ path("users_list/", views.users_list, name="users_list"),
+ path('send_friend_request//', views.send_friend_request, name='send_friend_request'),
+ path("test/", views.test, name="test"),
+]
diff --git a/backend/authentication/utils.py b/backend/authentication/utils.py
new file mode 100644
index 000000000..6d80a87b4
--- /dev/null
+++ b/backend/authentication/utils.py
@@ -0,0 +1,5 @@
+def user_profile_picture_path(instance, filename):
+ # Assuming 'instance' is a User instance
+ return f'authentication/images/{instance.username}/{filename}'
+
+
diff --git a/backend/authentication/views.py b/backend/authentication/views.py
index 48cb145ca..90c3671a9 100644
--- a/backend/authentication/views.py
+++ b/backend/authentication/views.py
@@ -1,23 +1,67 @@
from django.shortcuts import render, HttpResponse, redirect
from django.contrib.auth.decorators import login_required
-from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.conf import settings
import requests
import os
import urllib
+from .models import User
+from django.core.files.base import ContentFile
+from django.contrib.auth import get_user_model
+from django.shortcuts import get_object_or_404
+from .models import FriendRequest
+
+
+# ----------------------------------------––--------------- HOME FUNCTION
@login_required(login_url='/login/')
def home(request):
- return render(request, "home.html")
+ context = {
+ 'username': request.user.username,
+ 'email': request.user.email,
+ }
+ print(request.user)
+ return render(request, 'home.html', context)
+
+# ----------------------------------------––--------------- LOGIN FUNCTION
# don't name it 'login' because it will conflict with the built-in login function
def my_login(request):
if request.user.is_authenticated:
return redirect("home")
- return render(request, "login.html")
+ if request.method == 'POST':
+ username = request.POST.get('username')
+ password = request.POST.get('password')
+
+
+ # Authenticate the user
+ user = authenticate(request, username=username, password=password)
+ print(f'Username: {username}')
+ print(f'Password: {password}')
+ print(f'User: {user}')
+
+ if user is not None:
+ # Authentication successful, log in the user
+ login(request, user)
+ return redirect('home') # Redirect to the home page or another desired destination
+ else:
+ # Authentication failed, display an error message
+ error_message = 'Invalid username or password. Please try again.'
+ return render(request, 'login.html', {'error_message': error_message})
+ # Render the login form
+ return render(request, 'login.html')
+
+# ----------------------------------------––--------------- LOGOUT FUNCTION
+def my_logout(request):
+ # Log the user out using Django's built-in logout function
+ logout(request)
+ # Redirect the user to the login page
+ return redirect('login') # Replace 'login' with the actual name or URL of your login view
+
+
+# ----------------------------------------––--------------- AUTHENTICATION CALLBACK FUNCTIONS
def auth_callback(request):
if request.method == "GET":
@@ -40,36 +84,45 @@ def auth_callback(request):
# ---------------------------------------––---------------- GET USER DATA FROM 42 SERVER RESPONSE
# id will be implemented later, once we have a modified User model
# id = user_response.json()["id"]
+ # Extract user information from the response
username = user_response.json()["login"]
first_name = user_response.json()["first_name"]
last_name = user_response.json()["last_name"]
email = user_response.json()["email"]
- # picture will be implemented later, once we have a modified User model
- # picture = user_response.json()["image"]["link"]
+ picture_url = user_response.json()["image"]["versions"]["medium"]
+ titles = user_response.json().get("titles", [])
+ title = ""
+ if titles:
+ title = titles[0].get("name", "")
+ title = str(title).split()[0] if title else ""
- # -----------------------------------------––-------------- CREATE USER TO AUTHENTICATE AND LOGIN
- # user is a Model variable
- # created is a boolean variable
user, created = User.objects.get_or_create(
- username=username,
+ username=username,
defaults={
- 'username' : username,
- 'first_name': first_name,
- 'last_name': last_name,
- 'email': email
+ 'username': username,
+ 'first_name': first_name,
+ 'last_name': last_name,
+ 'email': email,
+ 'title': title,
}
)
if created:
print("\t\t\tNew user has been added!!!")
+ response = requests.get(picture_url)
+ if response.status_code == 200:
+ user.profile_picture.save(f"{username}_profile_picture.jpg", ContentFile(response.content), save=True)
else:
print("\t\t\tUser already exists!!!")
+
+ print(user)
login(request, user)
# ---------------------------------------––---------------- REDIRECT TO HOME PAGE
return redirect("home")
return HttpResponse("Auth callback Error, bad token maybe!!")
+# ----------------------------------------––--------------- AUTHENTICATION FUNCTIONS
def auth(request):
auth_url = "https://api.intra.42.fr/oauth/authorize"
params = {
@@ -79,13 +132,8 @@ def auth(request):
}
return redirect(f"{auth_url}?{urllib.parse.urlencode(params)}")
-def my_logout(request):
- # Log the user out using Django's built-in logout function
- logout(request)
-
- # Redirect the user to the login page
- return redirect('login') # Replace 'login' with the actual name or URL of your login view
+# ----------------------------------------––--------------- REGISTER FUNCTION
def register(request):
if request.user.is_authenticated:
return redirect("home")
@@ -101,7 +149,7 @@ def register(request):
user = User.objects.create_user(username=username, email=email, password=password,
first_name=first_name, last_name=last_name)
# Log the user in
- # login(request, user)
+ login(request, user)
print("\t\t\tNew user has been added!!!")
print(f'Username: {user.username}')
print(f'Email: {user.email}')
@@ -111,3 +159,56 @@ def register(request):
# Redirect to a success page or home
return redirect('home') # Change 'home' to the actual name of your home page or dashboard
return render(request, 'register.html')
+
+
+# ----------------------------------------––--------------- TEST FUNCTION
+def test(request):
+ # User data
+ username = 'Jason'
+ password = 'Bourne'
+
+ # Create or get the user
+ user, created = User.objects.get_or_create(username=username)
+ user.set_password(password)
+ user.save()
+
+ # Print messages for demonstration purposes
+ if created:
+ print("User created")
+ else:
+ print("User already exists")
+
+ print(user)
+
+ # Pass the user object to the template
+ return render(request, 'test.html', {'user': user})
+
+
+# ----------------------------------------––--------------- USERS LIST FUNCTION
+def users_list(request):
+ # Get all users from the database
+ users = User.objects.all()
+
+ # Pass the users to the template
+ return render(request, 'users_list.html', {'users': users})
+
+
+def has_friend_request_sent(from_user, to_user):
+ return FriendRequest.objects.filter(from_user=from_user, to_user=to_user, status='pending').exists()
+
+def send_friend_request(request, to_user_id):
+ # Get the 'to_user' object using the 'to_user_id'
+ to_user = get_object_or_404(User, pk=to_user_id)
+
+ # Check if a friend request already exists or if the users are the same
+ existing_request = FriendRequest.objects.filter(from_user=request.user, to_user=to_user).first()
+ if existing_request or request.user == to_user:
+ # Handle the case where a request already exists or trying to send a request to oneself
+ # You may want to display an error message or redirect to a different page
+ pass
+ else:
+ # Create a new friend request
+ friend_request = FriendRequest(from_user=request.user, to_user=to_user)
+ friend_request.save()
+
+ return redirect('users_list') # Redirect to the user's profile page or any other desired page
\ No newline at end of file
diff --git a/backend/backend/settings.py b/backend/backend/settings.py
index 18c7b69f1..4f7d8b3eb 100644
--- a/backend/backend/settings.py
+++ b/backend/backend/settings.py
@@ -11,6 +11,7 @@
"""
from pathlib import Path
+import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -20,7 +21,7 @@
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = 'django-insecure-ej^v-=x0xri%*-u@r0(+)pbc+onq+^rupromej&wxag1esu(f4'
+SECRET_KEY = 'django-insecure-#klz0g4gt37#*8aou2@a&u-k)rofekot&_7$o8ee1^=er*=1&0'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
@@ -40,8 +41,7 @@
'django.contrib.messages',
'django.contrib.staticfiles',
- 'authentication',
- # 'leaderboard',
+ 'authentication',
]
MIDDLEWARE = [
@@ -78,6 +78,15 @@
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
+# THIS IS THE DEFAULT DATABASE CONFIGURATION
+# DATABASES = {
+# 'default': {
+# 'ENGINE': 'django.db.backends.sqlite3',
+# 'NAME': BASE_DIR / 'db.sqlite3',
+# }
+# }
+
+# THIS IS THE DATABASE CONFIGURATION FOR THE DOCKER CONTAINER
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
@@ -89,7 +98,6 @@
}
}
-
# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
@@ -130,3 +138,12 @@
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+
+# For the custom user model to work we need to include this line
+AUTH_USER_MODEL = 'authentication.User'
+
+STATIC_URL = '/static/'
+STATICFILES_DIRS = [BASE_DIR / 'static']
+
+MEDIA_URL = '/media/'
+MEDIA_ROOT = BASE_DIR / 'media'
\ No newline at end of file
diff --git a/backend/backend/urls.py b/backend/backend/urls.py
index 9dca6e82d..d621ec5bf 100644
--- a/backend/backend/urls.py
+++ b/backend/backend/urls.py
@@ -16,10 +16,10 @@
"""
from django.contrib import admin
from django.urls import path, include
+from django.conf import settings
+from django.conf.urls.static import static
urlpatterns = [
- path('', include('authentication.urls')),
- # path('leaderboard/', include('leaderboard.urls')),
- # path('home/', include('authentication.urls')),
path('admin/', admin.site.urls),
-]
+ path('', include('authentication.urls')),
+] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
diff --git a/backend/chat/__init__.py b/backend/chat/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/backend/chat/admin.py b/backend/chat/admin.py
deleted file mode 100644
index 8c38f3f3d..000000000
--- a/backend/chat/admin.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.contrib import admin
-
-# Register your models here.
diff --git a/backend/chat/apps.py b/backend/chat/apps.py
deleted file mode 100644
index 2fe899ad4..000000000
--- a/backend/chat/apps.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from django.apps import AppConfig
-
-
-class ChatConfig(AppConfig):
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'chat'
diff --git a/backend/chat/migrations/__init__.py b/backend/chat/migrations/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/backend/chat/models.py b/backend/chat/models.py
deleted file mode 100644
index 71a836239..000000000
--- a/backend/chat/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.db import models
-
-# Create your models here.
diff --git a/backend/chat/tests.py b/backend/chat/tests.py
deleted file mode 100644
index 7ce503c2d..000000000
--- a/backend/chat/tests.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.test import TestCase
-
-# Create your tests here.
diff --git a/backend/chat/views.py b/backend/chat/views.py
deleted file mode 100644
index 91ea44a21..000000000
--- a/backend/chat/views.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.shortcuts import render
-
-# Create your views here.
diff --git a/backend/game/__init__.py b/backend/game/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/backend/game/admin.py b/backend/game/admin.py
deleted file mode 100644
index 8c38f3f3d..000000000
--- a/backend/game/admin.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.contrib import admin
-
-# Register your models here.
diff --git a/backend/game/apps.py b/backend/game/apps.py
deleted file mode 100644
index 8ad49cb8e..000000000
--- a/backend/game/apps.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from django.apps import AppConfig
-
-
-class GameConfig(AppConfig):
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'game'
diff --git a/backend/game/migrations/__init__.py b/backend/game/migrations/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/backend/game/models.py b/backend/game/models.py
deleted file mode 100644
index 71a836239..000000000
--- a/backend/game/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.db import models
-
-# Create your models here.
diff --git a/backend/game/tests.py b/backend/game/tests.py
deleted file mode 100644
index 7ce503c2d..000000000
--- a/backend/game/tests.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.test import TestCase
-
-# Create your tests here.
diff --git a/backend/game/views.py b/backend/game/views.py
deleted file mode 100644
index 91ea44a21..000000000
--- a/backend/game/views.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.shortcuts import render
-
-# Create your views here.
diff --git a/backend/leaderboard/__init__.py b/backend/leaderboard/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/backend/leaderboard/admin.py b/backend/leaderboard/admin.py
deleted file mode 100644
index 8c38f3f3d..000000000
--- a/backend/leaderboard/admin.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.contrib import admin
-
-# Register your models here.
diff --git a/backend/leaderboard/apps.py b/backend/leaderboard/apps.py
deleted file mode 100644
index 590a45294..000000000
--- a/backend/leaderboard/apps.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from django.apps import AppConfig
-
-
-class LeaderboardConfig(AppConfig):
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'leaderboard'
diff --git a/backend/leaderboard/migrations/0001_initial.py b/backend/leaderboard/migrations/0001_initial.py
deleted file mode 100644
index b53e51405..000000000
--- a/backend/leaderboard/migrations/0001_initial.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Generated by Django 5.0 on 2023-12-13 10:59
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- initial = True
-
- dependencies = [
- ('authentication', '0002_alter_user_id'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Friendship',
- fields=[
- ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('created_at', models.DateTimeField(auto_now_add=True)),
- ('receiver', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='friendship_receiver', to='authentication.user')),
- ('sender', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='friendship_sender', to='authentication.user')),
- ],
- options={
- 'unique_together': {('sender', 'receiver')},
- },
- ),
- ]
diff --git a/backend/leaderboard/migrations/0002_alter_friendship_unique_together_friendship_accepted_and_more.py b/backend/leaderboard/migrations/0002_alter_friendship_unique_together_friendship_accepted_and_more.py
deleted file mode 100644
index 35457f2b6..000000000
--- a/backend/leaderboard/migrations/0002_alter_friendship_unique_together_friendship_accepted_and_more.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Generated by Django 5.0 on 2023-12-13 12:27
-
-import django.db.models.deletion
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('authentication', '0002_alter_user_id'),
- # ('leaderboard', '0001_initial'),
- ]
-
- operations = [
- migrations.AlterUniqueTogether(
- name='friendship',
- unique_together=set(),
- ),
- migrations.AddField(
- model_name='friendship',
- name='accepted',
- field=models.BooleanField(default=False),
- ),
- migrations.AlterField(
- model_name='friendship',
- name='receiver',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='received_friend_requests', to='authentication.user'),
- ),
- migrations.AlterField(
- model_name='friendship',
- name='sender',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sent_friend_requests', to='authentication.user'),
- ),
- migrations.RemoveField(
- model_name='friendship',
- name='created_at',
- ),
- ]
diff --git a/backend/leaderboard/migrations/0003_delete_friendship.py b/backend/leaderboard/migrations/0003_delete_friendship.py
deleted file mode 100644
index 32b51c22a..000000000
--- a/backend/leaderboard/migrations/0003_delete_friendship.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Generated by Django 5.0 on 2023-12-15 09:23
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('leaderboard', '0002_alter_friendship_unique_together_friendship_accepted_and_more'),
- ]
-
- operations = [
- migrations.DeleteModel(
- name='Friendship',
- ),
- ]
diff --git a/backend/leaderboard/migrations/__init__.py b/backend/leaderboard/migrations/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/backend/leaderboard/models.py b/backend/leaderboard/models.py
deleted file mode 100644
index 370851e92..000000000
--- a/backend/leaderboard/models.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# from django.db import models
-# from authentication.models import User
-
-
-# class Friendship(models.Model):
-# sender = models.ForeignKey(User, related_name='sent_friend_requests', on_delete=models.CASCADE)
-# receiver = models.ForeignKey(User, related_name='received_friend_requests', on_delete=models.CASCADE)
-# accepted = models.BooleanField(default=False)
-
-# def __str__(self):
-# return f"{self.sender.username} - {self.receiver.username} ({'Accepted' if self.accepted else 'Pending'})"
\ No newline at end of file
diff --git a/backend/leaderboard/templates/leaderboard/leaderboard.html b/backend/leaderboard/templates/leaderboard/leaderboard.html
deleted file mode 100644
index 3064a24ba..000000000
--- a/backend/leaderboard/templates/leaderboard/leaderboard.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
- Document
-
-
-
- User List
-
-
- {% for user in users %}
- -
- {{ user.email }}
-
-
- {% endfor %}
-
-
-
-
\ No newline at end of file
diff --git a/backend/leaderboard/tests.py b/backend/leaderboard/tests.py
deleted file mode 100644
index 7ce503c2d..000000000
--- a/backend/leaderboard/tests.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.test import TestCase
-
-# Create your tests here.
diff --git a/backend/leaderboard/urls.py b/backend/leaderboard/urls.py
deleted file mode 100644
index 242731ebe..000000000
--- a/backend/leaderboard/urls.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# users_list/urls.py
-from django.urls import path
-from . import views
-
-urlpatterns = [
- # path('leaderboard/', views.leaderboard, name='leaderboard'),
- # path('send_friend_request/', views.send_friend_request, name='send_friend_request'),
- # Add other URL patterns as needed
-]
\ No newline at end of file
diff --git a/backend/leaderboard/views.py b/backend/leaderboard/views.py
deleted file mode 100644
index 1b5a5df0e..000000000
--- a/backend/leaderboard/views.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# # users_list/views.py
-# from django.shortcuts import render
-# # from authentication.models import User
-
-
-# def leaderboard(request):
-# users = User.objects.all()
-# # print("\t\t\t NUM OF USERS: ", end='')
-# # print(len(users))
-# # print(users)
-# # for user in users:
-# # print(user)
-# context = {'users' : users}
-# return render(request, 'leaderboard/leaderboard.html', context)
-
-
-
-# # NOT READY YET
-# def send_friend_request(request):
-# if request.method == 'POST':
-# sender_id = request.user.id # Assuming you have a logged-in user
-# receiver_id = request.POST.get('receiver_id')
-
-# # Check if the friendship already exists
-# existing_friendship = Friendship.objects.filter(sender_id=sender_id, receiver_id=receiver_id).first()
-
-# if existing_friendship:
-# messages.error(request, 'Friend request already sent.')
-# else:
-# # Create a new friendship request
-# friendship = Friendship(sender_id=sender_id, receiver_id=receiver_id)
-# friendship.save()
-# messages.success(request, 'Friend request sent successfully.')
-
-# return redirect('leaderboard')
-# else:
-# # Redirect to leaderboard page if the request method is not POST
-# return redirect('leaderboard')
\ No newline at end of file
diff --git a/backend/requirements.txt b/backend/requirements.txt
index d022601ab..37162a163 100644
--- a/backend/requirements.txt
+++ b/backend/requirements.txt
@@ -7,3 +7,4 @@ psycopg2-binary==2.9.9
requests==2.31.0
sqlparse==0.4.4
urllib3==2.1.0
+Pillow==10.1.0
diff --git a/docker-compose.yaml b/docker-compose.yaml
index fa01d105a..d3b61c3a8 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -15,32 +15,29 @@ services:
- 3000:3000
restart: unless-stopped
command: npm start
-# depends_on:
-# - backend
-
-# backend:
-# container_name: backend
-# env_file:
-# - ./.env
-# build:
-# context: .
-# dockerfile: docker/backend/backend.Dockerfile
-# image: transcendence_backend
-# volumes:
-# - ${PWD}:/app/
-# ports:
-# - 8000:8000
-# restart: unless-stopped
-# entrypoint: /app/docker/backend/backend.sh
-# depends_on:
-# - db
-# # need this shit properly pls
-# db:
-# image: postgres
-# environment:
-# POSTGRES_DB: transcend_users_db
-# POSTGRES_USER: transcend_user
-# POSTGRES_PASSWORD: transcend_pwd
-# ports:
-# - "5432:5432"
+ # backend:
+ # container_name: backend
+ # env_file:
+ # - ./.env
+ # build:
+ # context: .
+ # dockerfile: docker/backend/backend.Dockerfile
+ # image: transcendence_backend
+ # volumes:
+ # - ${PWD}:/app/
+ # ports:
+ # - 8000:8000
+ # # restart: unless-stopped
+ # depends_on:
+ # - db
+
+ # db:
+ # image: postgres
+ # container_name: database
+ # environment:
+ # POSTGRES_DB: transcend_users_db
+ # POSTGRES_USER: transcend_user
+ # POSTGRES_PASSWORD: transcend_pwd
+ # ports:
+ # - "5432:5432"
diff --git a/docker/backend/backend.Dockerfile b/docker/backend/backend.Dockerfile
index 4372685c7..6a2a08268 100644
--- a/docker/backend/backend.Dockerfile
+++ b/docker/backend/backend.Dockerfile
@@ -16,5 +16,5 @@ RUN chmod +x /app/backend.sh
EXPOSE 8000
-# ENTRYPOINT ["tail", "-f", "/dev/null"]
+ENTRYPOINT ["tail", "-f", "/dev/null"]
ENTRYPOINT ["docker/backend/backend.sh"]
\ No newline at end of file
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 228a41d5f..983d87be6 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -1621,9 +1621,9 @@
}
},
"@eslint/js": {
- "version": "8.55.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz",
- "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA=="
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
+ "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A=="
},
"@formatjs/ecma402-abstract": {
"version": "1.18.0",
@@ -1632,13 +1632,6 @@
"requires": {
"@formatjs/intl-localematcher": "0.5.2",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"@formatjs/fast-memoize": {
@@ -1647,13 +1640,6 @@
"integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==",
"requires": {
"tslib": "^2.4.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"@formatjs/icu-messageformat-parser": {
@@ -1664,13 +1650,6 @@
"@formatjs/ecma402-abstract": "1.18.0",
"@formatjs/icu-skeleton-parser": "1.7.0",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"@formatjs/icu-skeleton-parser": {
@@ -1680,13 +1659,6 @@
"requires": {
"@formatjs/ecma402-abstract": "1.18.0",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"@formatjs/intl": {
@@ -1701,13 +1673,6 @@
"@formatjs/intl-listformat": "7.5.3",
"intl-messageformat": "10.5.8",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"@formatjs/intl-displaynames": {
@@ -1718,13 +1683,6 @@
"@formatjs/ecma402-abstract": "1.18.0",
"@formatjs/intl-localematcher": "0.5.2",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"@formatjs/intl-listformat": {
@@ -1735,13 +1693,6 @@
"@formatjs/ecma402-abstract": "1.18.0",
"@formatjs/intl-localematcher": "0.5.2",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"@formatjs/intl-localematcher": {
@@ -1750,13 +1701,6 @@
"integrity": "sha512-txaaE2fiBMagLrR4jYhxzFO6wEdEG4TPMqrzBAcbr4HFUYzH/YC+lg6OIzKCHm8WgDdyQevxbAAV1OgcXctuGw==",
"requires": {
"tslib": "^2.4.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"@humanwhocodes/config-array": {
@@ -1779,6 +1723,59 @@
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw=="
},
+ "@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "requires": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="
+ },
+ "ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="
+ },
+ "string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "requires": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "requires": {
+ "ansi-regex": "^6.0.1"
+ }
+ },
+ "wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "requires": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ }
+ }
+ }
+ },
"@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -2669,6 +2666,12 @@
"fastq": "^1.6.0"
}
},
+ "@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "optional": true
+ },
"@pmmmwh/react-refresh-webpack-plugin": {
"version": "0.5.11",
"resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz",
@@ -2686,9 +2689,9 @@
}
},
"@remix-run/router": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.1.tgz",
- "integrity": "sha512-so+DHzZKsoOcoXrILB4rqDkMDy7NLMErRdOxvzvOKb507YINKUP4Di+shbTZDhSE/pBZ+vr7XGIpcOO0VLSA+Q=="
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.1.tgz",
+ "integrity": "sha512-Qg4DMQsfPNAs88rb2xkdk03N3bjK4jgX5fR24eHCTR9q6PrhZQZ4UJBPzCHJkIpTRN1UKxx2DzjZmnC+7Lj0Ow=="
},
"@rollup/plugin-babel": {
"version": "5.3.1",
@@ -2739,9 +2742,9 @@
}
},
"@rushstack/eslint-patch": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz",
- "integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA=="
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.1.tgz",
+ "integrity": "sha512-UY+FGM/2jjMkzQLn8pxcHGMaVLh9aEitG3zY2CiY7XHdLiz3bZOwa6oDxNqEMv7zZkV+cj5DOdz0cQ1BP5Hjgw=="
},
"@sinclair/typebox": {
"version": "0.27.8",
@@ -3002,9 +3005,9 @@
}
},
"@types/babel__generator": {
- "version": "7.6.7",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz",
- "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==",
+ "version": "7.6.8",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
"requires": {
"@babel/types": "^7.0.0"
}
@@ -3061,9 +3064,9 @@
}
},
"@types/eslint": {
- "version": "8.44.9",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.9.tgz",
- "integrity": "sha512-6yBxcvwnnYoYT1Uk2d+jvIfsuP4mb2EdIxFnrPABj5a/838qe5bGkNLFOiipX4ULQ7XVQvTxOh7jO+BTAiqsEw==",
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.0.tgz",
+ "integrity": "sha512-FlsN0p4FhuYRjIxpbdXovvHQhtlG05O1GG/RNWvdAxTboR438IOTwmrY/vLA+Xfgg06BTkP045M3vpFwTMv1dg==",
"requires": {
"@types/estree": "*",
"@types/json-schema": "*"
@@ -3186,9 +3189,9 @@
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="
},
"@types/node": {
- "version": "20.10.4",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz",
- "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==",
+ "version": "20.10.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz",
+ "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==",
"requires": {
"undici-types": "~5.26.4"
}
@@ -3222,9 +3225,9 @@
"integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw=="
},
"@types/qs": {
- "version": "6.9.10",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz",
- "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw=="
+ "version": "6.9.11",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz",
+ "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ=="
},
"@types/range-parser": {
"version": "1.2.7",
@@ -3242,9 +3245,9 @@
}
},
"@types/react-dom": {
- "version": "18.2.17",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz",
- "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==",
+ "version": "18.2.18",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz",
+ "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==",
"requires": {
"@types/react": "*"
}
@@ -4318,13 +4321,6 @@
"requires": {
"pascal-case": "^3.1.2",
"tslib": "^2.0.3"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"camelcase": {
@@ -4349,9 +4345,9 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001570",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz",
- "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw=="
+ "version": "1.0.30001571",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz",
+ "integrity": "sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ=="
},
"case-sensitive-paths-webpack-plugin": {
"version": "2.4.0",
@@ -5231,13 +5227,6 @@
"requires": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"dotenv": {
@@ -5255,6 +5244,11 @@
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="
},
+ "eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
+ },
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -5269,9 +5263,9 @@
}
},
"electron-to-chromium": {
- "version": "1.4.611",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.611.tgz",
- "integrity": "sha512-ZtRpDxrjHapOwxtv+nuth5ByB8clyn8crVynmRNGO3wG3LOp8RTcyZDqwaI6Ng6y8FCK2hVZmJoqwCskKbNMaw=="
+ "version": "1.4.616",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz",
+ "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg=="
},
"emittery": {
"version": "0.8.1",
@@ -5485,14 +5479,14 @@
}
},
"eslint": {
- "version": "8.55.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz",
- "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==",
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
+ "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.55.0",
+ "@eslint/js": "8.56.0",
"@humanwhocodes/config-array": "^0.11.13",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@@ -5670,9 +5664,9 @@
}
},
"eslint-plugin-import": {
- "version": "2.29.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz",
- "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==",
+ "version": "2.29.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz",
+ "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==",
"requires": {
"array-includes": "^3.1.7",
"array.prototype.findlastindex": "^1.2.3",
@@ -5690,7 +5684,7 @@
"object.groupby": "^1.0.1",
"object.values": "^1.1.7",
"semver": "^6.3.1",
- "tsconfig-paths": "^3.14.2"
+ "tsconfig-paths": "^3.15.0"
},
"dependencies": {
"debug": {
@@ -6105,9 +6099,9 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
},
"fastq": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
- "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz",
+ "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==",
"requires": {
"reusify": "^1.0.4"
}
@@ -6260,6 +6254,22 @@
"is-callable": "^1.1.3"
}
},
+ "foreground-child": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+ "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "dependencies": {
+ "signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="
+ }
+ }
+ },
"fork-ts-checker-webpack-plugin": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz",
@@ -6716,9 +6726,9 @@
}
},
"html-webpack-plugin": {
- "version": "5.5.4",
- "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.4.tgz",
- "integrity": "sha512-3wNSaVVxdxcu0jd4FpQFoICdqgxs4zIQQvj+2yQKFfBOnLETQ6X5CDWdeasuGlSsooFlMkEioWDTqBv1wvw5Iw==",
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz",
+ "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==",
"requires": {
"@types/html-minifier-terser": "^6.0.0",
"html-minifier-terser": "^6.0.2",
@@ -6943,13 +6953,6 @@
"@formatjs/fast-memoize": "2.2.0",
"@formatjs/icu-messageformat-parser": "2.7.3",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"ipaddr.js": {
@@ -7315,6 +7318,15 @@
"set-function-name": "^2.0.1"
}
},
+ "jackspeak": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
+ "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
+ "requires": {
+ "@isaacs/cliui": "^8.0.2",
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
"jake": {
"version": "10.8.7",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz",
@@ -9463,13 +9475,6 @@
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"requires": {
"tslib": "^2.0.3"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"lru-cache": {
@@ -9659,6 +9664,11 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
},
+ "minipass": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
+ "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ=="
+ },
"mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
@@ -9723,13 +9733,6 @@
"requires": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"node-forge": {
@@ -9979,13 +9982,6 @@
"requires": {
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"parent-module": {
@@ -10024,13 +10020,6 @@
"requires": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"path-exists": {
@@ -10053,6 +10042,22 @@
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
+ "path-scurry": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
+ "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
+ "requires": {
+ "lru-cache": "^9.1.1 || ^10.0.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz",
+ "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag=="
+ }
+ }
+ },
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
@@ -10516,9 +10521,9 @@
}
},
"postcss-modules-scope": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
- "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.0.tgz",
+ "integrity": "sha512-SaIbK8XW+MZbd0xHPf7kdfA/3eOt7vxJ72IRecn3EzuZVLr1r0orzf0MX/pN8m+NMDoo6X/SQd8oeKqGZd8PXg==",
"requires": {
"postcss-selector-parser": "^6.0.4"
}
@@ -11160,13 +11165,6 @@
"hoist-non-react-statics": "^3.3.2",
"intl-messageformat": "10.5.8",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
- }
}
},
"react-is": {
@@ -11180,20 +11178,20 @@
"integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A=="
},
"react-router": {
- "version": "6.20.1",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.1.tgz",
- "integrity": "sha512-ccvLrB4QeT5DlaxSFFYi/KR8UMQ4fcD8zBcR71Zp1kaYTC5oJKYAp1cbavzGrogwxca+ubjkd7XjFZKBW8CxPA==",
+ "version": "6.21.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.1.tgz",
+ "integrity": "sha512-W0l13YlMTm1YrpVIOpjCADJqEUpz1vm+CMo47RuFX4Ftegwm6KOYsL5G3eiE52jnJpKvzm6uB/vTKTPKM8dmkA==",
"requires": {
- "@remix-run/router": "1.13.1"
+ "@remix-run/router": "1.14.1"
}
},
"react-router-dom": {
- "version": "6.20.1",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.20.1.tgz",
- "integrity": "sha512-npzfPWcxfQN35psS7rJgi/EW0Gx6EsNjfdJSAk73U/HqMEJZ2k/8puxfwHFgDQhBGmS3+sjnGbMdMSV45axPQw==",
+ "version": "6.21.1",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.1.tgz",
+ "integrity": "sha512-QCNrtjtDPwHDO+AO21MJd7yIcr41UetYt5jzaB9Y1UYaPTCnVuJq6S748g1dE11OQlCFIQg+RtAA1SEZIyiBeA==",
"requires": {
- "@remix-run/router": "1.13.1",
- "react-router": "6.20.1"
+ "@remix-run/router": "1.14.1",
+ "react-router": "6.21.1"
}
},
"react-scripts": {
@@ -11333,9 +11331,9 @@
}
},
"regenerator-runtime": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
- "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"regenerator-transform": {
"version": "0.15.2",
@@ -12101,6 +12099,23 @@
}
}
},
+ "string-width-cjs": {
+ "version": "npm:string-width@4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "dependencies": {
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ }
+ }
+ },
"string.prototype.matchall": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz",
@@ -12180,6 +12195,14 @@
"ansi-regex": "^5.0.1"
}
},
+ "strip-ansi-cjs": {
+ "version": "npm:strip-ansi@6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
@@ -12223,35 +12246,50 @@
}
},
"sucrase": {
- "version": "3.34.0",
- "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
- "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==",
+ "version": "3.35.0",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
"requires": {
"@jridgewell/gen-mapping": "^0.3.2",
"commander": "^4.0.0",
- "glob": "7.1.6",
+ "glob": "^10.3.10",
"lines-and-columns": "^1.1.6",
"mz": "^2.7.0",
"pirates": "^4.0.1",
"ts-interface-checker": "^0.1.9"
},
"dependencies": {
+ "brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
"commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="
},
"glob": {
- "version": "7.1.6",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
- "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "version": "10.3.10",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
+ "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
"requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^2.3.5",
+ "minimatch": "^9.0.1",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
+ "path-scurry": "^1.10.1"
+ }
+ },
+ "minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "requires": {
+ "brace-expansion": "^2.0.1"
}
}
}
@@ -12355,9 +12393,9 @@
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
},
"tailwindcss": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.6.tgz",
- "integrity": "sha512-AKjF7qbbLvLaPieoKeTjG1+FyNZT6KaJMJPFeQyLfIp7l82ggH1fbHJSsYIvnbTFQOlkh+gBYpyby5GT1LIdLw==",
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz",
+ "integrity": "sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA==",
"requires": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",
@@ -12551,9 +12589,9 @@
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
},
"tsconfig-paths": {
- "version": "3.14.2",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz",
- "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==",
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+ "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
"requires": {
"@types/json5": "^0.0.29",
"json5": "^1.0.2",
@@ -12572,9 +12610,9 @@
}
},
"tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"tsutils": {
"version": "3.21.0",
@@ -12582,6 +12620,13 @@
"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
"requires": {
"tslib": "^1.8.1"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ }
}
},
"type-check": {
@@ -13094,9 +13139,9 @@
}
},
"whatwg-fetch": {
- "version": "3.6.19",
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz",
- "integrity": "sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw=="
+ "version": "3.6.20",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz",
+ "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="
},
"whatwg-mimetype": {
"version": "2.3.0",
@@ -13450,6 +13495,16 @@
"strip-ansi": "^6.0.0"
}
},
+ "wrap-ansi-cjs": {
+ "version": "npm:wrap-ansi@7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 7bcdc1f28..406dc34fa 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,8 +1,8 @@
{
"name": "frontend",
"version": "0.1.0",
- "homepage": "https://zstenger93.github.io/Transcendence",
"private": true,
+ "homepage": "https://zstenger93.github.io/Transcendence/",
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
diff --git a/frontend/src/App.js b/frontend/src/App.js
index e276e1aae..121220183 100644
--- a/frontend/src/App.js
+++ b/frontend/src/App.js
@@ -1,15 +1,21 @@
-import React from "react";
-import { I18nextProvider } from "react-i18next";
+import React, { useEffect } from "react";
+import { I18nextProvider, useTranslation } from "react-i18next";
import Translation from "./components/Translation";
import Home from "./components/Home";
import Chat from "./components/Chat";
import Games from "./components/Games";
import About from "./components/About";
+import NotFound from "./components/404";
import PongAi from "./components/PongAi";
import Sidebar from "./components/Sidebar";
import Welcome from "./components/Welcome";
import Profile from "./components/Profile";
-import backgroundImage from "./images/bg0.png";
+import HomeBackground from "./images/bg0.png";
+import MortyBackground0 from "./images/morty0.png";
+import MortyBackground1 from "./images/morty1.png";
+import MortyBackground2 from "./images/morty2.png";
+import MortyBackground3 from "./images/morty3.png";
+import MortyBackground4 from "./images/morty4.png";
import Matchmaking from "./components/Matchmaking";
import OriginalPong from "./components/OriginalPong";
import ChoosePongMode from "./components/ChoosePongMode";
@@ -18,43 +24,126 @@ import {
BrowserRouter as Router,
Route,
Routes,
- Navigate,
} from "react-router-dom";
+const PageWrapper = ({ children, image, showSidebar = true }) => {
+ return (
+
+ {showSidebar && }
+ {children}
+
+ );
+};
+
function App() {
+ const { i18n } = useTranslation();
const basename = process.env.NODE_ENV === 'production' ? '/Transcendence' : '';
+ useEffect(() => {
+ const storedLanguage = localStorage.getItem('i18nextLng');
+ if (storedLanguage && i18n.language !== storedLanguage) {
+ i18n.changeLanguage(storedLanguage);
+ }
+ }, [i18n]);
+
return (
- } />
-
-
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
-
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+
}
/>
diff --git a/frontend/src/App.test.js b/frontend/src/App.test.js
index 57c684b45..99994aac6 100644
--- a/frontend/src/App.test.js
+++ b/frontend/src/App.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { render, screen, prettyDOM, waitFor } from '@testing-library/react';
+import { render, screen, fireEvent, prettyDOM, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import App from './App';
import { within } from '@testing-library/dom';
@@ -13,7 +13,7 @@ test('renders Sign In button', () => {
console.log(prettyDOM(container));
- const signInButton = screen.getByText('Sign In');
+ const signInButton = screen.getByText('Sign In via 42');
expect(signInButton).toBeInTheDocument();
});
@@ -21,7 +21,7 @@ test('renders Sign In button', () => {
test('clicks on Sign In button and interacts with Sidebar', async () => {
const { container } = render();
- const signInButton = screen.getByText('Sign In');
+ const signInButton = screen.getByText('Sign In via 42');
userEvent.click(signInButton);
await waitFor(() => screen.getByText('Logout'));
@@ -29,13 +29,43 @@ test('clicks on Sign In button and interacts with Sidebar', async () => {
const homeLink = screen.getByText('Home');
const chatLink = screen.getByText('Channels & Private Messages');
+ const gamesLink = screen.getByText('Play & Watch Games');
+ const profileLink = screen.getByText('Profile');
+ const aboutLink = screen.getByText('About Us');
+ const logoutLink = screen.getByText('Logout');
userEvent.click(homeLink);
userEvent.click(chatLink);
- console.log(prettyDOM(container, 50000));
-
+ userEvent.click(gamesLink);
+ userEvent.click(profileLink);
+ userEvent.click(aboutLink);
+ userEvent.click(logoutLink);
});
+// test('async test for page data', async () => {
+// const { container } = render();
+
+// const signInButton = screen.getByText('Sign In via 42');
+// userEvent.click(signInButton);
+
+// await waitFor(() => screen.getByText('Logout'));
+// await waitFor(() => screen.getByText('Welcome To'));
+// });
+
+// jest.mock('react-i18next', () => ({
+// useTranslation: () => ({ t: key => key })
+// }));
+
+// test('async test for page data', async () => {
+// render();
+
+// const signInButton = screen.getByText('Sign In via 42');
+// userEvent.click(signInButton);
+
+// await waitFor(() => screen.getByText('Logout'));
+// await waitFor(() => screen.getByText('Welcome To'));
+// });
+
// test('renders chat page', () => {
// render();
// const chatElement = screen.getByText('Chat');
diff --git a/frontend/src/components/404.js b/frontend/src/components/404.js
new file mode 100644
index 000000000..3566b46d1
--- /dev/null
+++ b/frontend/src/components/404.js
@@ -0,0 +1,51 @@
+import React, { useState, useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+import NotFoundVideo from '../images/404.mp4';
+import { useTranslation } from 'react-i18next';
+
+const NotFound = ({ currentLanguage }) => {
+ const navigate = useNavigate();
+ const [counter, setCounter] = useState(10);
+ const { t, i18n } = useTranslation();
+
+ useEffect(() => {
+ const storedLanguage = localStorage.getItem('myAppLanguage');
+ if (storedLanguage && i18n.language !== storedLanguage) {
+ i18n.changeLanguage(storedLanguage);
+ }
+
+ if (counter > 0) {
+ const timer = setTimeout(() => {
+ setCounter(counter - 1);
+ }, 1150);
+ return () => clearTimeout(timer);
+ } else {
+ navigate('/');
+ }
+ }, [counter, navigate, i18n, currentLanguage]);
+
+ return (
+
+
+
+
+ 404 !@#$
+
+
+ {t('Your portal gun must be busted ...')}
+
+
+
+ {t('Your curious ass will be redirected in')}
+ {counter}
+
+
+ );
+};
+
+export default NotFound;
\ No newline at end of file
diff --git a/frontend/src/components/About.js b/frontend/src/components/About.js
index ceff5c026..a3cca3747 100644
--- a/frontend/src/components/About.js
+++ b/frontend/src/components/About.js
@@ -3,7 +3,6 @@ import Slider from "react-slick";
import { useTranslation } from "react-i18next";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
-import backgroundImage from "../images/bg0.png";
function About() {
const { t } = useTranslation();
@@ -57,7 +56,6 @@ function About() {
{teamMembers.map((member, index) => (
diff --git a/frontend/src/components/Chat.js b/frontend/src/components/Chat.js
index 4de2ce62d..454165277 100644
--- a/frontend/src/components/Chat.js
+++ b/frontend/src/components/Chat.js
@@ -106,7 +106,7 @@ function Chat() {
@@ -184,7 +184,7 @@ function Chat() {
diff --git a/frontend/src/components/ChoosePongMode.js b/frontend/src/components/ChoosePongMode.js
index 136395264..e36396781 100644
--- a/frontend/src/components/ChoosePongMode.js
+++ b/frontend/src/components/ChoosePongMode.js
@@ -12,40 +12,40 @@ function ChoosePongMode() {
{t("Original Pong")}
{t("Multiplayer")}
{t("Modded Pong")}
{t("Pong against AI")}
{t("3D Pong")}
@@ -53,7 +53,8 @@ function ChoosePongMode() {
diff --git a/frontend/src/components/Games.js b/frontend/src/components/Games.js
index 25b4038ff..8fba0e286 100644
--- a/frontend/src/components/Games.js
+++ b/frontend/src/components/Games.js
@@ -1,5 +1,4 @@
import React from "react";
-import backgroundImage from "../images/bg0.png";
import { Link } from "react-router-dom";
function Games() {
@@ -10,7 +9,7 @@ function Games() {
"https://www.youtube.com/embed/dQw4w9WgXcQ?controls=0&showinfo=0&rel=0&autoplay=1&mute=1&loop=1&playlist=dQw4w9WgXcQ",
},
{
- name: "BRAINFUCK",
+ name: "Emotional Damage",
video:
"https://www.youtube.com/embed/dQw4w9WgXcQ?controls=0&showinfo=0&rel=0&autoplay=1&mute=1&loop=1&playlist=dQw4w9WgXcQ",
},
@@ -19,8 +18,7 @@ function Games() {
return (
{tiles.map((tile, index) => (
@@ -28,7 +26,8 @@ function Games() {
key={index}
to="/choosepongmode"
className="relative bg-white p-4 rounded shadow
- border-black border-2 text-black overflow-hidden m-2"
+ border-black border-2 text-black font-nosifer
+ overflow-hidden m-2"
style={{ width: "30vw", height: "16.875vw" }}
>
{tile.name}
diff --git a/frontend/src/components/Home.js b/frontend/src/components/Home.js
index 3bf6f0d22..4d37c3162 100644
--- a/frontend/src/components/Home.js
+++ b/frontend/src/components/Home.js
@@ -1,12 +1,10 @@
import React from "react";
-import backgroundImage from "../images/bg0.png";
import WelcomeMessage from "./WelcomeMessage";
function Home() {
return (
diff --git a/frontend/src/components/Matchmaking.js b/frontend/src/components/Matchmaking.js
index cb377cf90..b8b63d48e 100644
--- a/frontend/src/components/Matchmaking.js
+++ b/frontend/src/components/Matchmaking.js
@@ -1,12 +1,10 @@
import React from "react";
-import backgroundImage from "../images/bg0.png";
function Matchmaking() {
return (
);
}
diff --git a/frontend/src/components/Profile.js b/frontend/src/components/Profile.js
index febc61e43..45d4796e9 100644
--- a/frontend/src/components/Profile.js
+++ b/frontend/src/components/Profile.js
@@ -278,6 +278,7 @@ function Profile() {