From 31308471a4f04de329c5999884b9e4fa99152ee7 Mon Sep 17 00:00:00 2001 From: James Wild Date: Sat, 4 Nov 2023 09:01:05 +0000 Subject: [PATCH 1/3] ignore redis file --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index f8c2ca5..863fc72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .env - -.DS_STORE \ No newline at end of file +.DS_STORE +dump.rdb \ No newline at end of file From 08d78547b4b711e1c1651f765c4c0b8a4e4f0081 Mon Sep 17 00:00:00 2001 From: James Wild Date: Sat, 4 Nov 2023 11:11:35 +0000 Subject: [PATCH 2/3] On first login, show users the help page --- todoqueue_backend/accounts/admin.py | 9 ++++++- .../0004_customuser_has_logged_in.py | 18 +++++++++++++ todoqueue_backend/accounts/models.py | 2 ++ todoqueue_backend/accounts/serializers.py | 1 + todoqueue_backend/accounts/urls.py | 2 ++ todoqueue_backend/accounts/views.py | 13 +++++++++ .../todoqueue_backend/settings.py | 22 ++++++++++++--- todoqueue_frontend/src/api/users.js | 27 ++++++++++++++++++- .../src/components/login/Login.js | 23 ++++++++++++---- .../popups/HouseholdDetailsPopup.js | 4 +-- .../src/components/tasks/Tasks.js | 4 +-- 11 files changed, 110 insertions(+), 15 deletions(-) create mode 100644 todoqueue_backend/accounts/migrations/0004_customuser_has_logged_in.py diff --git a/todoqueue_backend/accounts/admin.py b/todoqueue_backend/accounts/admin.py index ef7d172..3ae4e89 100644 --- a/todoqueue_backend/accounts/admin.py +++ b/todoqueue_backend/accounts/admin.py @@ -11,6 +11,7 @@ class CustomUserAdmin(UserAdmin): "date_joined", "is_active", "is_staff", + "has_logged_in", "brownie_point_credit", "brownie_point_debit", ) @@ -35,7 +36,13 @@ class CustomUserAdmin(UserAdmin): ("Dates", {"fields": ("last_login", "date_joined")}), ( "Additional Info", - {"fields": ("brownie_point_credit", "brownie_point_debit")}, + { + "fields": ( + "brownie_point_credit", + "brownie_point_debit", + "has_logged_in", + ) + }, ), ) add_fieldsets = ( diff --git a/todoqueue_backend/accounts/migrations/0004_customuser_has_logged_in.py b/todoqueue_backend/accounts/migrations/0004_customuser_has_logged_in.py new file mode 100644 index 0000000..90fd105 --- /dev/null +++ b/todoqueue_backend/accounts/migrations/0004_customuser_has_logged_in.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2023-11-04 09:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0003_alter_customuser_username'), + ] + + operations = [ + migrations.AddField( + model_name='customuser', + name='has_logged_in', + field=models.BooleanField(default=False), + ), + ] diff --git a/todoqueue_backend/accounts/models.py b/todoqueue_backend/accounts/models.py index 5f2d4ca..bae54a1 100644 --- a/todoqueue_backend/accounts/models.py +++ b/todoqueue_backend/accounts/models.py @@ -42,6 +42,8 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): date_joined = models.DateTimeField(default=timezone.now) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) + + has_logged_in = models.BooleanField(default=False) brownie_point_credit = models.JSONField(default=dict) brownie_point_debit = models.JSONField(default=dict) diff --git a/todoqueue_backend/accounts/serializers.py b/todoqueue_backend/accounts/serializers.py index f36b687..a1e1710 100644 --- a/todoqueue_backend/accounts/serializers.py +++ b/todoqueue_backend/accounts/serializers.py @@ -22,6 +22,7 @@ class Meta: "email", "username", "date_joined", + "has_logged_in", "brownie_point_credit", "brownie_point_debit", ) diff --git a/todoqueue_backend/accounts/urls.py b/todoqueue_backend/accounts/urls.py index 23c6fe3..77b0c4c 100644 --- a/todoqueue_backend/accounts/urls.py +++ b/todoqueue_backend/accounts/urls.py @@ -2,6 +2,7 @@ from rest_framework.routers import DefaultRouter from .views import ( CustomUserViewSet, + GetUserData, AuthView, LogoutView, RegisterView, @@ -19,6 +20,7 @@ path("auth/", AuthView.as_view(), name="auth"), path("token/", jwt_views.TokenObtainPairView.as_view(), name="token_obtain_pair"), path("token/refresh/", jwt_views.TokenRefreshView.as_view(), name="token_refresh"), + path("user_info/", GetUserData.as_view(), name="user_info"), path("logout/", LogoutView.as_view(), name="logout"), path("register/", RegisterView.as_view(), name="register"), path( diff --git a/todoqueue_backend/accounts/views.py b/todoqueue_backend/accounts/views.py index e08a72f..2318d2f 100644 --- a/todoqueue_backend/accounts/views.py +++ b/todoqueue_backend/accounts/views.py @@ -52,6 +52,19 @@ def check_permissions(self, request): ) +class GetUserData(APIView): + permission_classes = (IsAuthenticated,) + + def get(self, request): + """Return the serialization of the user who authenticated this request""" + logger.info("Getting serialization of a single user") + user = request.user + serializer = CustomUserSerializer(user) + serialized_data = serializer.data + logger.info(f"User data: {serialized_data}") + + return Response(serialized_data) + class AuthView(APIView): permission_classes = (IsAuthenticated,) diff --git a/todoqueue_backend/todoqueue_backend/settings.py b/todoqueue_backend/todoqueue_backend/settings.py index a196a9d..5a37d88 100644 --- a/todoqueue_backend/todoqueue_backend/settings.py +++ b/todoqueue_backend/todoqueue_backend/settings.py @@ -17,9 +17,6 @@ from logging import getLogger, INFO, DEBUG, basicConfig -basicConfig(level=DEBUG) -logger = getLogger(__name__) - # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -31,7 +28,24 @@ SECRET_KEY = config("DJANGO_SECRET", default=os.urandom(32)) # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = os.environ.get("DJANGO_DEBUG", "false").lower() == "true" +env_debug = os.environ.get("DJANGO_DEBUG", "false").lower() +if env_debug.isdigit(): + env_debug = int(env_debug) == 1 +else: + env_debug = env_debug in ["true", "yes"] + +logging_level = os.environ.get("DJANGO_LOGGING_LEVEL", "info").lower() + +if logging_level.lower() == "debug": + basicConfig(level=DEBUG) +else: + basicConfig(level=INFO) + +logger = getLogger(__name__) +logger.info(f"Logging level: {logging_level}") +logger.info(f"Django is using DEBUG = {env_debug}") + +DEBUG = env_debug web_port = config("DJANGO_HOST_PORT", default=8000, cast=int) logger.info("Whilelisting host for CSRF: {}".format(config("FRONTEND_URL", default=None))) diff --git a/todoqueue_frontend/src/api/users.js b/todoqueue_frontend/src/api/users.js index a4f986b..6e85b51 100644 --- a/todoqueue_frontend/src/api/users.js +++ b/todoqueue_frontend/src/api/users.js @@ -77,7 +77,7 @@ export const logOutUser = async () => { } -export const fetchUsers = async (selectedHousehold) => { +export const fetchHouseholdUsers = async (selectedHousehold) => { if (!selectedHousehold) { console.log("No household selected - skipping get users."); return null; @@ -107,6 +107,31 @@ export const fetchUsers = async (selectedHousehold) => { }; +export const fetchUserData = async () => { + const get_user_url = `${backend_url}/api/user_info/`; + + console.log("Getting my user data"); + try { + const res = await axios.get( + get_user_url, + { + headers: { + 'Content-Type': 'application/json', + } + }) + if (res.status !== 200) { + console.log("Failed to get my user data"); + return null; + } + console.log("I got my user data!", res.data); + return res.data; + } catch (error) { + console.error("An error occurred while fetching my user data", error); + return null; + } +} + + export const forgotPassword = async (email) => { console.log("Resetting password"); diff --git a/todoqueue_frontend/src/components/login/Login.js b/todoqueue_frontend/src/components/login/Login.js index 1c0f236..6d6774b 100644 --- a/todoqueue_frontend/src/components/login/Login.js +++ b/todoqueue_frontend/src/components/login/Login.js @@ -3,7 +3,7 @@ import { useState, useEffect } from "react"; // Define the Login function. import "./Login.css"; import "../../utils/buttons.css"; -import { loginUser } from "../../api/users"; +import { loginUser, fetchUserData } from "../../api/users"; import AlertMessage from "../popups/AlertPopup"; import Spinner from "../spinner/Spinner"; @@ -26,14 +26,27 @@ const Login = ({ setShowHouseholdSelector }) => { setShowSpinner(true); const data = await response; - setShowSpinner(false); if (data.error) { + setShowSpinner(false); setLoginError(data.error); } else if (data.success) { - setShowSpinner(false); - console.log("Login successful. Redirecting to /"); - window.location.href = "/"; + const res = await fetchUserData(); + + if (res === null) { + setShowSpinner(false); + setLoginError(""); + } + + if (res.has_logged_in) { + setShowSpinner(false); + console.log("Login successful. Redirecting to /"); + window.location.href = "/"; + } else { + setShowSpinner(false); + console.log("This is my first login. Redirecting to help page."); + window.location.href = "/help"; + } } } diff --git a/todoqueue_frontend/src/components/popups/HouseholdDetailsPopup.js b/todoqueue_frontend/src/components/popups/HouseholdDetailsPopup.js index 073ebe6..68e24cb 100644 --- a/todoqueue_frontend/src/components/popups/HouseholdDetailsPopup.js +++ b/todoqueue_frontend/src/components/popups/HouseholdDetailsPopup.js @@ -1,7 +1,7 @@ import React, { useEffect, useState, useRef } from 'react'; import BasePopup from './BasePopup'; -import { fetchUsers } from '../../api/users'; +import { fetchHouseholdUsers } from '../../api/users'; import { addUserToHousehold, removeUserFromHousehold, fetchSelectedHousehold } from '../../api/households'; import Spinner from '../spinner/Spinner'; @@ -20,7 +20,7 @@ const HouseholdDetailsPopup = React.forwardRef((props, ref) => { const updateUsers = async (id) => { try { console.log("Fetching users"); - const users = await fetchUsers(id); + const users = await fetchHouseholdUsers(id); if (users === null) { console.log("Closing popup"); props.closePopup(); diff --git a/todoqueue_frontend/src/components/tasks/Tasks.js b/todoqueue_frontend/src/components/tasks/Tasks.js index 2ad16a2..606812e 100644 --- a/todoqueue_frontend/src/components/tasks/Tasks.js +++ b/todoqueue_frontend/src/components/tasks/Tasks.js @@ -15,7 +15,7 @@ import CreateScheduledTaskPopup from '../popups/CreateScheduledTaskPopup'; import EditScheduledTaskPopup from '../popups/EditScheduledTaskPopup'; import { fetchTasks } from '../../api/tasks'; -import { fetchUsers } from '../../api/users'; +import { fetchHouseholdUsers } from '../../api/users'; const Tasks = ({ selectedHousehold, showSelectedHouseholdSelector, setShowHouseholdSelector }) => { @@ -168,7 +168,7 @@ const Tasks = ({ selectedHousehold, showSelectedHouseholdSelector, setShowHouseh const fetchSetUsers = async () => { - const data = await fetchUsers(selectedHousehold); + const data = await fetchHouseholdUsers(selectedHousehold); if (data === null) { setUsers([]); return; From 95b138655e9d06f7f3455cce345241ee7396c2bb Mon Sep 17 00:00:00 2001 From: James Wild Date: Sat, 4 Nov 2023 11:14:23 +0000 Subject: [PATCH 3/3] Add help to navbar --- todoqueue_frontend/src/components/navbar/navigation.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/todoqueue_frontend/src/components/navbar/navigation.js b/todoqueue_frontend/src/components/navbar/navigation.js index c236794..3789937 100644 --- a/todoqueue_frontend/src/components/navbar/navigation.js +++ b/todoqueue_frontend/src/components/navbar/navigation.js @@ -102,6 +102,10 @@ export function Navigation({ households, selectedHousehold, setSelectedHousehold )} + +