diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1ddf..00000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
deleted file mode 100644
index e3c8a4b7..00000000
--- a/.idea/workspace.xml
+++ /dev/null
@@ -1,1400 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {
- "customColor": "",
- "associatedIndex": 4
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
- false
- false
-
-
-
-
-
-
-
- 1714731586527
-
-
- 1714731586527
-
-
-
-
\ No newline at end of file
diff --git a/backend/nba_app/migrations/0003_follow_user_following.py b/backend/nba_app/migrations/0003_follow_user_following.py
new file mode 100644
index 00000000..1780907f
--- /dev/null
+++ b/backend/nba_app/migrations/0003_follow_user_following.py
@@ -0,0 +1,32 @@
+# Generated by Django 5.0.4 on 2024-05-09 22:33
+
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('nba_app', '0002_post'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Follow',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('followed', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='follower_set', to=settings.AUTH_USER_MODEL)),
+ ('follower', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='following_set', to=settings.AUTH_USER_MODEL)),
+ ],
+ options={
+ 'unique_together': {('follower', 'followed')},
+ },
+ ),
+ migrations.AddField(
+ model_name='user',
+ name='following',
+ field=models.ManyToManyField(related_name='followers', through='nba_app.Follow', to=settings.AUTH_USER_MODEL),
+ ),
+ ]
diff --git a/backend/nba_app/models.py b/backend/nba_app/models.py
index ff8e71ef..f3a98157 100644
--- a/backend/nba_app/models.py
+++ b/backend/nba_app/models.py
@@ -35,6 +35,9 @@ class User(AbstractBaseUser, PermissionsMixin):
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
+ following = models.ManyToManyField('self', symmetrical=False, through='Follow', related_name='followers')
+
+
objects = CustomUserManager()
USERNAME_FIELD = 'username'
@@ -64,5 +67,11 @@ class Comment(models.Model):
def __str__(self):
return f'{self.user.username} on {self.post.post_id}: {self.content}'
-
-
\ No newline at end of file
+
+class Follow(models.Model):
+ follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name='following_set')
+ followed = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follower_set')
+ created_at = models.DateTimeField(auto_now_add=True)
+
+ class Meta:
+ unique_together = ('follower', 'followed')
diff --git a/backend/nba_app/urls.py b/backend/nba_app/urls.py
index f660bfda..15575f14 100644
--- a/backend/nba_app/urls.py
+++ b/backend/nba_app/urls.py
@@ -6,6 +6,10 @@
path('signup/', views.sign_up, name='signup'),
path('login/', views.log_in, name='login'),
path('feed/', views.feed, name='feed'),
+ path('profile_view_edit/', views.profile_view_edit, name='profile_view_edit'),
+ path('follow_user/', views.follow_user, name='follow_user'),
+ path('unfollow_user/', views.unfollow_user, name='unfollow_user'),
+ path('reset_password/', views.reset_password, name='reset_password'),
path('post/', views.post, name='post'),
path('search/', views.search, name='search'),
path('team/', views.team, name='team'),
diff --git a/backend/nba_app/views.py b/backend/nba_app/views.py
index 9a615053..ffb0e2d9 100644
--- a/backend/nba_app/views.py
+++ b/backend/nba_app/views.py
@@ -6,7 +6,7 @@
from django.middleware.csrf import get_token
from django.http import JsonResponse, HttpResponse
from django.urls import reverse
-from .models import User, Post, Comment
+from .models import User, Post, Comment, Follow
import requests
def sign_up(request):
@@ -106,11 +106,158 @@ def create_comment(request, post_id):
return render(request, 'comment.html', {'post_id': post_id})
+
def post_detail(request, post_id):
post = Post.objects.get(post_id=post_id)
- comments = post.comments.all()
+ comments = Comment.objects.get(post = post) #post.comments.all()
return render(request, 'post_detail.html', {'post': post, 'comments': comments})
+
+def profile_view_edit(request):
+ if request.method == 'POST':
+ new_username = request.POST.get('username')
+ new_email = request.POST.get('email')
+ new_profile_picture = request.FILES.get('profile_picture')
+ new_bio = request.POST.get('bio')
+ new_password = request.POST.get('password')
+
+ user = request.user
+
+ # Update username if provided
+ if new_username:
+ user.username = new_username
+
+ # Update email if provided
+ if new_email:
+ user.email = new_email
+
+ # Update profile picture if provided
+ if new_profile_picture:
+ user.profile_picture = new_profile_picture
+
+ # Update bio if provided
+ if new_bio:
+ user.bio = new_bio
+
+ # Update password if provided
+ if new_password:
+ user.set_password(new_password)
+
+ user.save()
+
+ return JsonResponse({'message': 'Account information updated successfully.'}, status=200)
+
+ # if request.method == 'GET':
+ user = request.user
+ following_count = user.following.count()
+ followers_count = user.followers.count()
+ posts = Post.objects.filter(user=user)
+ #post_contents = [post.content for post in posts]
+ data = {
+ 'username': user.username,
+ 'email': user.email,
+ 'bio': user.bio,
+ #'profile_picture': user.profile_picture.url if user.profile_picture else None,
+ # Add any other fields you want to include in the response
+ 'following_count': following_count,
+ 'followers_count': followers_count,
+ 'posts': [{'content': post.content, 'created_at': post.created_at} for post in posts]
+ }
+ return JsonResponse(data, status=200)
+
+
+
+
+def reset_password(request):
+ if request.method != 'POST':
+ return JsonResponse({'error': 'Only POST requests are allowed.'}, status=405)
+
+ email = request.POST.get('email')
+ username = request.POST.get('username')
+ new_password = request.POST.get('new_password')
+
+ # Check if either email or username is provided
+ if not email and not username:
+ return JsonResponse({'error': 'Email address or username is required in the request.'}, status=400)
+
+ # Retrieve the user by email or username
+ user = None
+ if email:
+ try:
+ user = User.objects.get(email=email)
+ except User.DoesNotExist:
+ pass
+ elif username:
+ try:
+ user = User.objects.get(username=username)
+ except User.DoesNotExist:
+ pass
+
+ if not user:
+ return JsonResponse({'error': 'User not found.'}, status=404)
+
+ # Check if new password is provided
+ if not new_password:
+ return JsonResponse({'error': 'New password is required.'}, status=400)
+
+ # Set the new password
+ user.set_password(new_password)
+ user.save()
+
+ return JsonResponse({'message': 'Password reset successful.'}, status = 200)
+
+
+
+
+def follow_user(request):
+ if request.method != 'POST':
+ return JsonResponse({'error': 'Only POST requests are allowed.'}, status=405)
+
+ user_id = request.POST.get('user_id')
+
+ if request.user.user_id == user_id:
+ return JsonResponse({'error': 'You cannot follow yourself.'}, status=400)
+
+ # Retrieve the user to follow
+ try:
+ followed_user = User.objects.get(pk=user_id)
+ except User.DoesNotExist:
+ return JsonResponse({'error': 'User not found.'}, status=404)
+
+ # Check if the user is already following the given user
+ already_following = Follow.objects.filter(follower=request.user, followed=followed_user).exists()
+ if already_following:
+ return JsonResponse({'message': 'You are already following this user.'}, status = 400)
+
+ # Create a new follow instance
+ Follow.objects.create(follower=request.user, followed=followed_user)
+ return JsonResponse({'message': 'You have successfully followed the user.'}, status=200)
+
+
+
+
+def unfollow_user(request):
+ if request.method != 'POST':
+ return JsonResponse({'error': 'Only POST requests are allowed.'}, status=405)
+
+ user_id = request.POST.get('user_id')
+
+ # Retrieve the user to unfollow
+ try:
+ followed_user = User.objects.get(pk=user_id)
+ except User.DoesNotExist:
+ return JsonResponse({'error': 'User not found.'}, status=404)
+
+ # Check if the user is already not following the given user
+ follow_instance = Follow.objects.filter(follower=request.user, followed=followed_user).first()
+ if not follow_instance:
+ return HttpResponse('You are not following this user.', status=400)
+
+ # Delete the follow instance
+ follow_instance.delete()
+ return JsonResponse({'message': 'You have successfully unfollowed the user.'}, status=200)
+
+
@login_required
def feed(request):
# Only authenticated users can access this view
diff --git a/backend/nba_project/settings.py b/backend/nba_project/settings.py
index b8872103..2ec4b9e2 100644
--- a/backend/nba_project/settings.py
+++ b/backend/nba_project/settings.py
@@ -16,7 +16,7 @@
import os
# Load environment variables from .env file
-load_dotenv('././.env')
+load_dotenv('./.env')
print('DB_HOST:', os.getenv('DB_HOST'))
print('DB_USER:', os.getenv('DB_USER'))
@@ -100,8 +100,8 @@
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.getenv('DB_NAME'),
- 'HOST': os.getenv('DB_HOST'),
- 'PORT': os.getenv('DB_PORT'),
+ 'HOST': '64.226.89.39',#os.getenv('DB_HOST'),
+ 'PORT': '3307',#os.getenv('DB_PORT'),
'USER': os.getenv('DB_USER'),
'PASSWORD': os.getenv('DB_PASSWORD'),
}
diff --git a/frontend/.env.example b/frontend/.env.example
deleted file mode 100644
index dae007ed..00000000
--- a/frontend/.env.example
+++ /dev/null
@@ -1 +0,0 @@
-REACT_APP_DEPLOY_MACHINE_IP=127.0.0.1
\ No newline at end of file