diff --git a/backend/authentications/urls.py b/backend/authentications/urls.py index 75c5914..6029eea 100644 --- a/backend/authentications/urls.py +++ b/backend/authentications/urls.py @@ -1,13 +1,11 @@ from django.urls import path from rest_framework_simplejwt import views as jwt_views -from authentications.views import ObtainTokenPairWithCustomView, GreetingView, GoogleLogin, GoogleRetrieveUserInfo, CheckAccessTokenAndRefreshToken +from authentications.views import ObtainTokenPairWithCustomView, GoogleRetrieveUserInfo, CheckAccessTokenAndRefreshToken urlpatterns = [ path('token/obtain/', jwt_views.TokenObtainPairView.as_view(), name='token_create'), path('token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'), path('token/custom_obtain/', ObtainTokenPairWithCustomView.as_view(), name='token_create_custom'), - path('hello/', GreetingView.as_view(), name='hello_world'), - path('dj-rest-auth/google/', GoogleLogin.as_view(), name="google_login"), path('auth/google/', GoogleRetrieveUserInfo.as_view()), path('auth/status/', CheckAccessTokenAndRefreshToken.as_view(), name='check_token_status') ] \ No newline at end of file diff --git a/backend/authentications/views.py b/backend/authentications/views.py index 167581b..87f662e 100644 --- a/backend/authentications/views.py +++ b/backend/authentications/views.py @@ -7,17 +7,12 @@ from django.conf import settings from django.contrib.auth.hashers import make_password from rest_framework import status -from rest_framework.permissions import IsAuthenticated, AllowAny +from rest_framework.permissions import AllowAny from rest_framework.response import Response from rest_framework.views import APIView from rest_framework_simplejwt.tokens import RefreshToken from rest_framework_simplejwt.authentication import JWTAuthentication - -from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter - -from dj_rest_auth.registration.views import SocialLoginView - from google_auth_oauthlib.flow import InstalledAppFlow from authentications.access_token_cache import store_token @@ -69,39 +64,6 @@ class ObtainTokenPairWithCustomView(APIView): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) -class GreetingView(APIView): - """ - Hello World View. - Returns a greeting and user information for authenticated users. - """ - permission_classes = (IsAuthenticated,) - - def get(self, request): - """ - Retrieve a greeting message and user information. - """ - user = request.user - user_info = { - "username": user.username, - } - response_data = { - "message": "Hello, world!", - "user_info": user_info, - } - return Response(response_data, status=status.HTTP_200_OK) - - -class GoogleLogin(SocialLoginView): - """ - Google Login View. - Handles Google OAuth2 authentication. - """ - # permission_classes = (AllowAny,) - adapter_class = GoogleOAuth2Adapter - # client_class = OAuth2Client - # callback_url = 'http://localhost:8000/accounts/google/login/callback/' - - class GoogleRetrieveUserInfo(APIView): """ Retrieve user information from Google and create a user if not exists. diff --git a/backend/users/migrations/0005_alter_userstats_endurance_and_more.py b/backend/users/migrations/0005_alter_userstats_endurance_and_more.py index 35fe6f7..76ec5c3 100644 --- a/backend/users/migrations/0005_alter_userstats_endurance_and_more.py +++ b/backend/users/migrations/0005_alter_userstats_endurance_and_more.py @@ -25,7 +25,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='userstats', name='luck', - field=models.IntegerField(default=users.models.random_luck, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(50)]), + field=models.IntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(50)]), ), migrations.AlterField( model_name='userstats', diff --git a/backend/users/models.py b/backend/users/models.py index 7a765a6..2fe1df6 100644 --- a/backend/users/models.py +++ b/backend/users/models.py @@ -31,14 +31,12 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): # Fields for authentication USERNAME_FIELD = 'email' - REQUIRED_FIELDS = ['username', 'first_name'] + REQUIRED_FIELDS = [] def __str__(self): # String representation of the user return self.username - -def random_luck(): - return random.randint(1, 50) + class UserStats(models.Model): """ diff --git a/backend/users/views.py b/backend/users/views.py index af201b7..9d022e3 100644 --- a/backend/users/views.py +++ b/backend/users/views.py @@ -7,6 +7,8 @@ from rest_framework.response import Response from rest_framework.views import APIView from rest_framework.parsers import MultiPartParser +from rest_framework_simplejwt.tokens import RefreshToken + from users.serializers import CustomUserSerializer, UpdateProfileSerializer from users.models import CustomUser @@ -25,7 +27,9 @@ class CustomUserCreate(APIView): if serializer.is_valid(): user = serializer.save() if user: - return Response(serializer.data, status=status.HTTP_201_CREATED) + refresh = RefreshToken.for_user(user) + return Response(data={'access_token': str(refresh.access_token), 'refresh_token': str(refresh),}, + status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs index 1a8aa39..809eec3 100644 --- a/frontend/.eslintrc.cjs +++ b/frontend/.eslintrc.cjs @@ -13,5 +13,6 @@ module.exports = { plugins: ["react-refresh"], rules: { "react-refresh/only-export-components": ["warn", { allowConstantExport: true }], + "react/prop-types": 0, }, }; diff --git a/frontend/package.json b/frontend/package.json index 70698dc..f057dce 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -31,6 +31,7 @@ "@syncfusion/ej2-base": "^23.1.41", "@syncfusion/ej2-kanban": "^23.1.36", "@tremor/react": "^3.11.1", + "@wojtekmaj/react-daterange-picker": "^5.4.4", "axios": "^1.6.1", "bootstrap": "^5.3.2", "dotenv": "^16.3.1", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 143df2b..22fdadd 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -68,6 +68,9 @@ dependencies: '@tremor/react': specifier: ^3.11.1 version: 3.11.1(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)(tailwindcss@3.3.5) + '@wojtekmaj/react-daterange-picker': + specifier: ^5.4.4 + version: 5.4.4(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) axios: specifier: ^1.6.1 version: 1.6.2 @@ -1554,6 +1557,29 @@ packages: resolution: {integrity: sha512-+i7+JmNiE/3c9FKxzWFi2IjRJ+KzZl1QPu6QNrsgaa2MuBgXvUy4gA1TVzf/JMdIIloB76xSKikTWuyYAIVLww==} dev: false + /@wojtekmaj/react-daterange-picker@5.4.4(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-EoHFD2SHG1ZeBfdQ9NYaO9MzcdKXy8gikxxFlO3f7HJ/tOGI6/Vxt752sgNnCGsF4JlqVoWVHweyxYOExumRdA==} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.37 + clsx: 2.0.0 + make-event-props: 1.6.2 + prop-types: 15.8.1 + react: 18.2.0 + react-calendar: 4.6.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) + react-date-picker: 10.5.2(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) + react-fit: 1.7.1(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) + transitivePeerDependencies: + - '@types/react-dom' + dev: false + /acorn-jsx@5.3.2(acorn@8.11.2): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 1ab242f..a917ca5 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,21 +1,19 @@ -import { useEffect } from "react"; import "./App.css"; -import { Route, Routes, Navigate } from "react-router-dom"; import axios from "axios"; -import TestAuth from "./components/testAuth"; -import LoginPage from "./components/authentication/LoginPage"; -import SignUpPage from "./components/authentication/SignUpPage"; -import NavBar from "./components/navigations/Navbar"; -import Calendar from "./components/calendar/calendar"; -import KanbanPage from "./components/kanbanBoard/kanbanPage"; -import IconSideNav from "./components/navigations/IconSideNav"; -import Eisenhower from "./components/EisenhowerMatrix/Eisenhower"; -import PrivateRoute from "./PrivateRoute"; -import ProfileUpdatePage from "./components/profilePage"; -import Dashboard from "./components/dashboard/dashboard"; +import { useEffect } from "react"; +import { Route, Routes, Navigate } from "react-router-dom"; +import { LoginPage } from "./components/authentication/LoginPage"; +import { SignUp } from "./components/authentication/SignUpPage"; +import { NavBar } from "./components/navigations/Navbar"; +import { Calendar } from "./components/calendar/calendar"; +import { KanbanPage } from "./components/kanbanBoard/kanbanPage"; +import { SideNav } from "./components/navigations/IconSideNav"; +import { Eisenhower } from "./components/EisenhowerMatrix/Eisenhower"; +import { PrivateRoute } from "./PrivateRoute"; +import { ProfileUpdatePage } from "./components/profile/profilePage"; +import { Dashboard } from "./components/dashboard/dashboard"; import { LandingPage } from "./components/landingPage/LandingPage"; -import PublicRoute from "./PublicRoute"; - +import { PublicRoute } from "./PublicRoute"; import { useAuth } from "./hooks/AuthHooks"; const baseURL = import.meta.env.VITE_BASE_URL; @@ -48,9 +46,7 @@ const App = () => { setIsAuthenticated(false); } }) - .catch((error) => { - console.error("Error checking login status:", error.message); - }); + .catch((error) => {}); }; checkLoginStatus(); @@ -70,7 +66,7 @@ const NonAuthenticatedComponents = () => { } /> }> - } /> + } /> } /> @@ -81,7 +77,7 @@ const NonAuthenticatedComponents = () => { const AuthenticatedComponents = () => { return (
- +
@@ -90,7 +86,6 @@ const AuthenticatedComponents = () => { }> } /> - } /> }> } /> diff --git a/frontend/src/PrivateRoute.jsx b/frontend/src/PrivateRoute.jsx index 01afc6a..3daa62b 100644 --- a/frontend/src/PrivateRoute.jsx +++ b/frontend/src/PrivateRoute.jsx @@ -1,9 +1,7 @@ import { Navigate, Outlet } from "react-router-dom"; import { useAuth } from "src/hooks/AuthHooks"; -const PrivateRoute = () => { +export const PrivateRoute = () => { const { isAuthenticated } = useAuth(); return isAuthenticated ? : ; }; - -export default PrivateRoute; diff --git a/frontend/src/PublicRoute.jsx b/frontend/src/PublicRoute.jsx index ffdc39c..69f980a 100644 --- a/frontend/src/PublicRoute.jsx +++ b/frontend/src/PublicRoute.jsx @@ -1,9 +1,7 @@ import { Navigate, Outlet } from "react-router-dom"; import { useAuth } from "src/hooks/AuthHooks"; -const PublicRoute = () => { +export const PublicRoute = () => { const { isAuthenticated } = useAuth(); return isAuthenticated ? : ; }; - -export default PublicRoute; diff --git a/frontend/src/api/AuthenticationApi.jsx b/frontend/src/api/AuthenticationApi.jsx index bca81d5..e029404 100644 --- a/frontend/src/api/AuthenticationApi.jsx +++ b/frontend/src/api/AuthenticationApi.jsx @@ -1,32 +1,27 @@ import axios from "axios"; -import axiosInstance from "./AxiosConfig"; +import { axiosInstance } from "./AxiosConfig"; const baseURL = import.meta.env.VITE_BASE_URL; // Function for user login -const apiUserLogin = (data) => { +export const apiUserLogin = (data) => { return axiosInstance .post("token/obtain/", data) - .then((response) => { - console.log(response.statusText); - - return response; - }) + .then((response) => response) .catch((error) => { - console.log("apiUserLogin error: ", error); - return error; + throw error; }); }; // Function for user logout -const apiUserLogout = () => { +export const apiUserLogout = () => { axiosInstance.defaults.headers["Authorization"] = ""; // Clear authorization header localStorage.removeItem("access_token"); // Remove access token localStorage.removeItem("refresh_token"); // Remove refresh token }; // Function for Google login -const googleLogin = async (token) => { +export const googleLogin = async (token) => { axios.defaults.withCredentials = true; let res = await axios.post(`${baseURL}auth/google/`, { code: token, @@ -35,35 +30,14 @@ const googleLogin = async (token) => { return await res; }; -// Function to get 'hello' data -const getGreeting = () => { - return axiosInstance - .get("hello") - .then((response) => { - return response; - }) - .catch((error) => { - return error; - }); -}; - // Function to register -const createUser = async (formData) => { +export const createUser = async (formData) => { try { axios.defaults.withCredentials = true; - const response = axios.post(`${baseURL}user/create/`, formData); - // const response = await axiosInstance.post('/user/create/', formData); + const response = await axios.post(`${baseURL}user/create/`, formData); return response.data; } catch (e) { - console.log(e); + console.error("Error in createUser function:", e); + throw e; } }; - -// Export the functions and Axios instance -export default { - apiUserLogin, - apiUserLogout, - getGreeting: getGreeting, - googleLogin, - createUser, -}; diff --git a/frontend/src/api/AxiosConfig.jsx b/frontend/src/api/AxiosConfig.jsx index b037386..29ed6c7 100644 --- a/frontend/src/api/AxiosConfig.jsx +++ b/frontend/src/api/AxiosConfig.jsx @@ -3,7 +3,7 @@ import { redirect } from "react-router-dom"; const baseURL = import.meta.env.VITE_BASE_URL; -const axiosInstance = axios.create({ +export const axiosInstance = axios.create({ baseURL: baseURL, timeout: 5000, headers: { @@ -13,6 +13,14 @@ const axiosInstance = axios.create({ }, }); +axiosInstance.interceptors.request.use((config) => { + const access_token = localStorage.getItem("access_token"); + if (access_token) { + config.headers.Authorization = `Bearer ${access_token}`; + } + return config; +}); + // handling token refresh on 401 Unauthorized errors axiosInstance.interceptors.response.use( (response) => response, @@ -43,5 +51,3 @@ axiosInstance.interceptors.response.use( return Promise.reject(error); } ); - -export default axiosInstance; diff --git a/frontend/src/api/TaskApi.jsx b/frontend/src/api/TaskApi.jsx index daad9c3..098d934 100644 --- a/frontend/src/api/TaskApi.jsx +++ b/frontend/src/api/TaskApi.jsx @@ -1,4 +1,4 @@ -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; const baseURL = import.meta.env.VITE_BASE_URL; diff --git a/frontend/src/assets/calendar.png b/frontend/src/assets/calendar.png deleted file mode 100644 index 8c30ce3..0000000 Binary files a/frontend/src/assets/calendar.png and /dev/null differ diff --git a/frontend/src/assets/home.png b/frontend/src/assets/home.png deleted file mode 100644 index c40c6b2..0000000 Binary files a/frontend/src/assets/home.png and /dev/null differ diff --git a/frontend/src/assets/pie-chart.png b/frontend/src/assets/pie-chart.png deleted file mode 100644 index 376d9e9..0000000 Binary files a/frontend/src/assets/pie-chart.png and /dev/null differ diff --git a/frontend/src/assets/planning.png b/frontend/src/assets/planning.png deleted file mode 100644 index 13a6bb2..0000000 Binary files a/frontend/src/assets/planning.png and /dev/null differ diff --git a/frontend/src/assets/plus.png b/frontend/src/assets/plus.png deleted file mode 100644 index a5252f5..0000000 Binary files a/frontend/src/assets/plus.png and /dev/null differ diff --git a/frontend/src/assets/react.svg b/frontend/src/assets/react.svg deleted file mode 100644 index 6c87de9..0000000 --- a/frontend/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/src/components/EisenhowerMatrix/Eisenhower.jsx b/frontend/src/components/EisenhowerMatrix/Eisenhower.jsx index ccfc01e..cc19aaa 100644 --- a/frontend/src/components/EisenhowerMatrix/Eisenhower.jsx +++ b/frontend/src/components/EisenhowerMatrix/Eisenhower.jsx @@ -1,7 +1,7 @@ import { useState, useEffect } from "react"; import { FiAlertCircle, FiClock, FiXCircle, FiCheckCircle } from "react-icons/fi"; import { readTodoTasks } from "../../api/TaskApi"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; function EachBlog({ name, colorCode, contentList, icon }) { const [tasks, setTasks] = useState(contentList); @@ -55,7 +55,7 @@ function EachBlog({ name, colorCode, contentList, icon }) { ); } -function Eisenhower() { +export function Eisenhower() { const [tasks, setTasks] = useState([]); useEffect(() => { @@ -108,5 +108,3 @@ function Eisenhower() {
); } - -export default Eisenhower; diff --git a/frontend/src/components/FlaotingParticles.jsx b/frontend/src/components/FlaotingParticles.jsx new file mode 100644 index 0000000..c6d103a --- /dev/null +++ b/frontend/src/components/FlaotingParticles.jsx @@ -0,0 +1,91 @@ +import { useCallback } from "react"; +import Particles from "react-tsparticles"; +import { loadFull } from "tsparticles"; + +export function FloatingParticles() { + const particlesInit = useCallback(async (engine) => { + await loadFull(engine); + }, []); + + return ( +
+ +
+ ); +} diff --git a/frontend/src/components/authentication/LoginPage.jsx b/frontend/src/components/authentication/LoginPage.jsx index dff40ab..3b306a2 100644 --- a/frontend/src/components/authentication/LoginPage.jsx +++ b/frontend/src/components/authentication/LoginPage.jsx @@ -1,26 +1,19 @@ -import { useEffect, useState } from "react"; +import { useState } from "react"; import { useNavigate, redirect } from "react-router-dom"; import { useGoogleLogin } from "@react-oauth/google"; -import { useCallback } from "react"; -import Particles from "react-tsparticles"; -import { loadFull } from "tsparticles"; -import refreshAccessToken from "./refreshAcessToken"; -import axiosapi from "../../api/AuthenticationApi"; import { FcGoogle } from "react-icons/fc"; import { useAuth } from "src/hooks/AuthHooks"; +import { FloatingParticles } from "../FlaotingParticles"; +import { NavPreLogin } from "../navigations/NavPreLogin"; +import { apiUserLogin, googleLogin } from "src/api/AuthenticationApi"; -function LoginPage() { +export function LoginPage() { const { setIsAuthenticated } = useAuth(); const Navigate = useNavigate(); - useEffect(() => { - if (!refreshAccessToken()) { - Navigate("/"); - } - }, []); - const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); + const [error, setError] = useState(null); const handleEmailChange = (event) => { setEmail(event.target.value); @@ -29,26 +22,23 @@ function LoginPage() { const handlePasswordChange = (event) => { setPassword(event.target.value); }; + const handleSubmit = (event) => { event.preventDefault(); // Send a POST request to the authentication API - axiosapi - .apiUserLogin({ - email: email, - password: password, - }) + apiUserLogin({ + email: email, + password: password, + }) .then((res) => { - // On successful login, store tokens and set the authorization header localStorage.setItem("access_token", res.data.access); localStorage.setItem("refresh_token", res.data.refresh); - axiosapi.axiosInstance.defaults.headers["Authorization"] = "Bearer " + res.data.access; setIsAuthenticated(true); redirect("/"); }) .catch((err) => { - console.log("Login failed"); - console.log(err); + setError("Incorrect username or password"); }); }; @@ -57,7 +47,7 @@ function LoginPage() { redirect_uri: "postmessage", onSuccess: async (response) => { try { - const loginResponse = await axiosapi.googleLogin(response.code); + const loginResponse = await googleLogin(response.code); if (loginResponse && loginResponse.data) { const { access_token, refresh_token } = loginResponse.data; @@ -72,147 +62,81 @@ function LoginPage() { }, onError: (errorResponse) => console.log(errorResponse), }); - { - /* Particles Loader*/ - } - const particlesInit = useCallback(async (engine) => { - console.log(engine); - await loadFull(engine); - }, []); - - const particlesLoaded = useCallback(async (container) => { - console.log(container); - }, []); return ( -
- {/* Particles Container */} -
- -
- {/* Login Box */} -
-
-

Login

- {/* Email Input */} -
- - -
- {/* Password Input */} -
- - -
- {/* Login Button */} - -
OR
- {/* Login with Google Button */} - - {/* Forgot Password Link */} -
- - Forgot your password? - +
+ +
+ {/* Login Box */} +
+
+

Log in to your account

+ {/* Error Message */} + {error && ( +
+ + + + {error} +
+ )} + {/* Email Input */} +
+ + +
+ {/* Password Input */} +
+ + +
+ {/* Login Button */} + +
OR
+ {/* Login with Google Button */} +
+
+ +
); } - -export default LoginPage; diff --git a/frontend/src/components/authentication/SignUpPage.jsx b/frontend/src/components/authentication/SignUpPage.jsx index 0139867..08628e8 100644 --- a/frontend/src/components/authentication/SignUpPage.jsx +++ b/frontend/src/components/authentication/SignUpPage.jsx @@ -1,29 +1,14 @@ import { useState } from "react"; import { useNavigate } from "react-router-dom"; -import axiosapi from "../../api/AuthenticationApi"; -import { useCallback } from "react"; -import Particles from "react-tsparticles"; -import { loadFull } from "tsparticles"; import { FcGoogle } from "react-icons/fc"; import { useGoogleLogin } from "@react-oauth/google"; +import { NavPreLogin } from "../navigations/NavPreLogin"; import { useAuth } from "src/hooks/AuthHooks"; +import { createUser, googleLogin } from "src/api/AuthenticationApi"; -function Copyright(props) { - return ( -
- {"Copyright © "} - - TurTask - {" "} - {new Date().getFullYear()} - {"."} -
- ); -} - -export default function SignUp() { +export function SignUp() { const Navigate = useNavigate(); - const { setIsAuthenticated } = useAuth; + const { setIsAuthenticated } = useAuth(); const [formData, setFormData] = useState({ email: "", @@ -38,47 +23,48 @@ export default function SignUp() { setIsSubmitting(true); setError(null); + const delay = (ms) => new Promise((res) => setTimeout(res, ms)); + try { - axiosapi.createUser(formData); + const data = await createUser(formData); + localStorage.setItem("access_token", data.access_token); + localStorage.setItem("refresh_token", data.refresh_token); + await delay(200); + setIsAuthenticated(true); + Navigate("/"); } catch (error) { console.error("Error creating user:", error); setError("Registration failed. Please try again."); } finally { setIsSubmitting(false); } - Navigate("/login"); }; - const handleChange = (e) => { - const { name, value } = e.target; - setFormData({ ...formData, [name]: value }); - console.log(formData); + const handleEmailChange = (e) => { + setFormData({ ...formData, email: e.target.value }); }; - { - /* Particles Loader*/ - } - const particlesInit = useCallback(async (engine) => { - console.log(engine); - await loadFull(engine); - }, []); - const particlesLoaded = useCallback(async (container) => { - console.log(container); - }, []); + const handleUsernameChange = (e) => { + setFormData({ ...formData, username: e.target.value }); + }; + + const handlePasswordChange = (e) => { + setFormData({ ...formData, password: e.target.value }); + }; const googleLoginImplicit = useGoogleLogin({ flow: "auth-code", redirect_uri: "postmessage", onSuccess: async (response) => { try { - const loginResponse = await axiosapi.googleLogin(response.code); + const loginResponse = await googleLogin(response.code); if (loginResponse && loginResponse.data) { const { access_token, refresh_token } = loginResponse.data; localStorage.setItem("access_token", access_token); localStorage.setItem("refresh_token", refresh_token); setIsAuthenticated(true); - Navigate("/"); + Navigate("/profile"); } } catch (error) { console.error("Error with the POST request:", error); @@ -89,140 +75,76 @@ export default function SignUp() { }); return ( -
- {/* Particles Container */} -
- -
-
-
- {/* Register Form */} -

Signup

- {/* Email Input */} -
- - -
- {/* Username Input */} -
- - -
- {/* Password Input */} -
- - -
-

+
+ +
+ {/* ... (other code) */} +
+
+ {/* Register Form */} +

Signup

+ {/* Email Input */} +
+ + +
+ {/* Username Input */} +
+ + +
+ {/* Password Input */} +
+ + +
+

- {/* Signups Button */} - -
OR
- {/* Login with Google Button */} - - {/* Already have an account? */} -
- Already have an account? + {/* Signups Button */} + +
OR
+ {/* Login with Google Button */} + + {/* Already have an account? */} +
-
diff --git a/frontend/src/components/authentication/refreshAcessToken.jsx b/frontend/src/components/authentication/refreshAcessToken.jsx deleted file mode 100644 index e07395b..0000000 --- a/frontend/src/components/authentication/refreshAcessToken.jsx +++ /dev/null @@ -1,39 +0,0 @@ -import axios from "axios"; - -const baseURL = import.meta.env.VITE_BASE_URL; - -async function refreshAccessToken() { - const refresh_token = localStorage.getItem("refresh_token"); - const access_token = localStorage.getItem("access_token"); - - if (access_token) { - return true; - } - - if (!refresh_token) { - return false; - } - - const refreshUrl = `${baseURL}token/refresh/`; - - try { - const response = await axios.post(refreshUrl, { refresh: refresh_token }); - - if (response.status === 200) { - // Successful refresh - save the new access token and refresh token - const newAccessToken = response.data.access; - const newRefreshToken = response.data.refresh; - - localStorage.setItem("access_token", newAccessToken); - localStorage.setItem("refresh_token", newRefreshToken); - - return true; - } else { - return false; - } - } catch (error) { - return false; - } -} - -export default refreshAccessToken; diff --git a/frontend/src/components/calendar/TaskDataHandler.jsx b/frontend/src/components/calendar/TaskDataHandler.jsx index ff8a5df..793ca4b 100644 --- a/frontend/src/components/calendar/TaskDataHandler.jsx +++ b/frontend/src/components/calendar/TaskDataHandler.jsx @@ -1,9 +1,9 @@ -import { readTodoTasks } from "../../api/TaskApi"; +import { readTodoTasks } from "src/api/TaskApi"; let eventGuid = 0; -const mapResponseToEvents = response => { - return response.map(item => ({ +const mapResponseToEvents = (response) => { + return response.map((item) => ({ id: item.id, title: item.title, start: item.start_event, diff --git a/frontend/src/components/calendar/calendar.jsx b/frontend/src/components/calendar/calendar.jsx index e4f1bdd..a85ea2d 100644 --- a/frontend/src/components/calendar/calendar.jsx +++ b/frontend/src/components/calendar/calendar.jsx @@ -5,9 +5,9 @@ import dayGridPlugin from "@fullcalendar/daygrid"; import timeGridPlugin from "@fullcalendar/timegrid"; import interactionPlugin from "@fullcalendar/interaction"; import { getEvents, createEventId } from "./TaskDataHandler"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; -export default class Calendar extends React.Component { +export class Calendar extends React.Component { state = { weekendsVisible: true, currentEvents: [], diff --git a/frontend/src/components/dashboard/Areachart.jsx b/frontend/src/components/dashboard/Areachart.jsx index 862fa21..cd6bb93 100644 --- a/frontend/src/components/dashboard/Areachart.jsx +++ b/frontend/src/components/dashboard/Areachart.jsx @@ -1,6 +1,6 @@ import { AreaChart, Title } from "@tremor/react"; import { useState, useEffect } from "react"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; export const AreaChartGraph = () => { const [areaChartDataArray, setAreaChartDataArray] = useState([]); diff --git a/frontend/src/components/dashboard/Barchart.jsx b/frontend/src/components/dashboard/Barchart.jsx index 63a2c4f..bf84a2b 100644 --- a/frontend/src/components/dashboard/Barchart.jsx +++ b/frontend/src/components/dashboard/Barchart.jsx @@ -1,6 +1,6 @@ import { BarChart, Title } from "@tremor/react"; import { useState, useEffect } from "react"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; export const BarChartGraph = () => { const [barchartDataArray, setBarChartDataArray] = useState([]); diff --git a/frontend/src/components/dashboard/DonutChart.jsx b/frontend/src/components/dashboard/DonutChart.jsx index ccab32f..63fc591 100644 --- a/frontend/src/components/dashboard/DonutChart.jsx +++ b/frontend/src/components/dashboard/DonutChart.jsx @@ -1,8 +1,8 @@ import { DonutChart } from "@tremor/react"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; import { useState, useEffect } from "react"; -export default function DonutChartGraph() { +export function DonutChartGraph() { const [donutData, setDonutData] = useState([]); useEffect(() => { diff --git a/frontend/src/components/dashboard/KpiCard.jsx b/frontend/src/components/dashboard/KpiCard.jsx index 47c7162..c5c3165 100644 --- a/frontend/src/components/dashboard/KpiCard.jsx +++ b/frontend/src/components/dashboard/KpiCard.jsx @@ -1,8 +1,8 @@ import { BadgeDelta, Card, Flex, Metric, ProgressBar, Text } from "@tremor/react"; import { useEffect, useState } from "react"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; -export default function KpiCard() { +export function KpiCard() { const [kpiCardData, setKpiCardData] = useState({ completedThisWeek: 0, completedLastWeek: 0, diff --git a/frontend/src/components/dashboard/ProgressCircle.jsx b/frontend/src/components/dashboard/ProgressCircle.jsx index c6d09b3..683781e 100644 --- a/frontend/src/components/dashboard/ProgressCircle.jsx +++ b/frontend/src/components/dashboard/ProgressCircle.jsx @@ -1,8 +1,8 @@ import { Card, Flex, ProgressCircle } from "@tremor/react"; import { useState, useEffect } from "react"; -import axiosInstance from "src/api/AxiosConfig"; +import { axiosInstance } from "src/api/AxiosConfig"; -export default function ProgressCircleChart() { +export function ProgressCircleChart() { const [progressData, setProgressData] = useState(0); useEffect(() => { diff --git a/frontend/src/components/dashboard/dashboard.jsx b/frontend/src/components/dashboard/dashboard.jsx index 761f0ca..31cc71f 100644 --- a/frontend/src/components/dashboard/dashboard.jsx +++ b/frontend/src/components/dashboard/dashboard.jsx @@ -1,16 +1,22 @@ import { Card, Grid, Tab, TabGroup, TabList, TabPanel, TabPanels, Text, Title, Legend } from "@tremor/react"; -import KpiCard from "./KpiCard"; +import { KpiCard } from "./KpiCard"; import { BarChartGraph } from "./Barchart"; -import DonutChartGraph from "./DonutChart"; +import { DonutChartGraph } from "./DonutChart"; import { AreaChartGraph } from "./Areachart"; -import ProgressCircleChart from "./ProgressCircle"; +import { ProgressCircleChart } from "./ProgressCircle"; +import { useState } from "react"; -export default function Dashboard() { +export function Dashboard() { + const [value, setValue] = useState({ + from: new Date(2021, 0, 1), + to: new Date(2023, 0, 7), + }); return (
Dashboard All of your progress will be shown right here. +
diff --git a/frontend/src/components/kanbanBoard/columnContainer.jsx b/frontend/src/components/kanbanBoard/columnContainer.jsx index 80bd445..819a980 100644 --- a/frontend/src/components/kanbanBoard/columnContainer.jsx +++ b/frontend/src/components/kanbanBoard/columnContainer.jsx @@ -3,13 +3,13 @@ import { BsFillTrashFill } from "react-icons/bs"; import { AiOutlinePlusCircle } from "react-icons/ai"; import { CSS } from "@dnd-kit/utilities"; import { useMemo, useState } from "react"; -import TaskCard from "./taskCard"; +import { TaskCard } from "./taskCard"; -function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { +export function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { const [editMode, setEditMode] = useState(false); const tasksIds = useMemo(() => { - return tasks.map(task => task.id); + return tasks.map((task) => task.id); }, [tasks]); const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({ @@ -78,12 +78,12 @@ function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks updateColumn(column.id, e.target.value)} + onChange={(e) => updateColumn(column.id, e.target.value)} autoFocus onBlur={() => { setEditMode(false); }} - onKeyDown={e => { + onKeyDown={(e) => { if (e.key !== "Enter") return; setEditMode(false); }} @@ -109,7 +109,7 @@ function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks {/* Column task container */}
- {tasks.map(task => ( + {tasks.map((task) => ( ))} @@ -126,5 +126,3 @@ function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks
); } - -export default ColumnContainer; diff --git a/frontend/src/components/kanbanBoard/columnContainerWrapper.jsx b/frontend/src/components/kanbanBoard/columnContainerWrapper.jsx index 478a529..b14adb1 100644 --- a/frontend/src/components/kanbanBoard/columnContainerWrapper.jsx +++ b/frontend/src/components/kanbanBoard/columnContainerWrapper.jsx @@ -1,6 +1,6 @@ -import ColumnContainer from "./columnContainer"; +import { ColumnContainer } from "./columnContainer"; -function ColumnContainerCard({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { +export function ColumnContainerCard({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { return (
); } - -export default ColumnContainerCard; diff --git a/frontend/src/components/kanbanBoard/kanbanBoard.jsx b/frontend/src/components/kanbanBoard/kanbanBoard.jsx index a4ecd79..a91b2db 100644 --- a/frontend/src/components/kanbanBoard/kanbanBoard.jsx +++ b/frontend/src/components/kanbanBoard/kanbanBoard.jsx @@ -1,13 +1,12 @@ import { useMemo, useState, useEffect } from "react"; -import ColumnContainerCard from "./columnContainerWrapper"; +import { ColumnContainerCard } from "./columnContainerWrapper"; import { DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from "@dnd-kit/core"; import { SortableContext, arrayMove } from "@dnd-kit/sortable"; import { createPortal } from "react-dom"; -import TaskCard from "./taskCard"; -import { AiOutlinePlusCircle } from "react-icons/ai"; -import axiosInstance from "src/api/AxiosConfig"; +import { TaskCard } from "./taskCard"; +import { axiosInstance } from "src/api/AxiosConfig"; -function KanbanBoard() { +export function KanbanBoard() { const [columns, setColumns] = useState([]); const columnsId = useMemo(() => columns.map((col) => col.id), [columns]); const [boardId, setBoardData] = useState(); @@ -26,40 +25,6 @@ function KanbanBoard() { }) ); - // Example - // { - // "id": 95, - // "title": "Test Todo", - // "notes": "Test TodoTest TodoTest Todo", - // "importance": 1, - // "difficulty": 1, - // "challenge": false, - // "fromSystem": false, - // "creation_date": "2023-11-20T19:50:16.369308Z", - // "last_update": "2023-11-20T19:50:16.369308Z", - // "is_active": true, - // "is_full_day_event": false, - // "start_event": "2023-11-20T19:49:49Z", - // "end_event": "2023-11-23T18:00:00Z", - // "google_calendar_id": null, - // "completed": true, - // "completion_date": "2023-11-20T19:50:16.369308Z", - // "priority": 3, - // "user": 1, - // "list_board": 1, - // "tags": [] - // } - // ] - - // [ - // { - // "id": 8, - // "name": "test", - // "position": 2, - // "board": 3 - // } - // ] - useEffect(() => { const fetchData = async () => { try { @@ -73,7 +38,6 @@ function KanbanBoard() { difficulty: task.difficulty, notes: task.notes, importance: task.importance, - difficulty: task.difficulty, challenge: task.challenge, fromSystem: task.fromSystem, creation_date: task.creation_date, @@ -149,31 +113,6 @@ function KanbanBoard() { ))}
- {/* create new column */} -
{createPortal( @@ -409,10 +348,4 @@ function KanbanBoard() { }); } } - - function generateId() { - return Math.floor(Math.random() * 10001); - } } - -export default KanbanBoard; diff --git a/frontend/src/components/kanbanBoard/kanbanPage.jsx b/frontend/src/components/kanbanBoard/kanbanPage.jsx index 37671ae..9225ae7 100644 --- a/frontend/src/components/kanbanBoard/kanbanPage.jsx +++ b/frontend/src/components/kanbanBoard/kanbanPage.jsx @@ -1,12 +1,12 @@ -import KanbanBoard from "./kanbanBoard"; -import React, { useState } from 'react'; +import { KanbanBoard } from "./kanbanBoard"; +import { useState } from "react"; -const KanbanPage = () => { - const [activeTab, setActiveTab] = useState('kanban'); +export const KanbanPage = () => { + const [activeTab, setActiveTab] = useState("kanban"); - const handleTabClick = (tabId) => { - setActiveTab(tabId); - }; + const handleTabClick = (tabId) => { + setActiveTab(tabId); + }; return (
@@ -29,10 +29,7 @@ const KanbanPage = () => {
-
-
+
); }; - -export default KanbanPage; diff --git a/frontend/src/components/kanbanBoard/taskCard.jsx b/frontend/src/components/kanbanBoard/taskCard.jsx index 2c5053f..1a151c8 100644 --- a/frontend/src/components/kanbanBoard/taskCard.jsx +++ b/frontend/src/components/kanbanBoard/taskCard.jsx @@ -2,9 +2,9 @@ import { useState } from "react"; import { BsFillTrashFill } from "react-icons/bs"; import { useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; -import TaskDetailModal from "./taskDetailModal"; +import { TaskDetailModal } from "./taskDetailModal"; -function TaskCard({ task, deleteTask, updateTask}) { +export function TaskCard({ task, deleteTask, updateTask }) { const [mouseIsOver, setMouseIsOver] = useState(false); const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({ @@ -15,7 +15,6 @@ function TaskCard({ task, deleteTask, updateTask}) { }, }); - const style = { transition, transform: CSS.Transform.toString(transform), @@ -45,7 +44,7 @@ function TaskCard({ task, deleteTask, updateTask}) { description={task.description} tags={task.tags} difficulty={task.difficulty} - challenge={task.challenge} + f challenge={task.challenge} importance={task.importance} />
); } - -export default TaskCard; diff --git a/frontend/src/components/kanbanBoard/taskDetailModal.jsx b/frontend/src/components/kanbanBoard/taskDetailModal.jsx index ddf954b..e151d8f 100644 --- a/frontend/src/components/kanbanBoard/taskDetailModal.jsx +++ b/frontend/src/components/kanbanBoard/taskDetailModal.jsx @@ -1,9 +1,9 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { FaTasks, FaRegListAlt } from "react-icons/fa"; import { FaPlus } from "react-icons/fa6"; import { TbChecklist } from "react-icons/tb"; -function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId }) { +export function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId }) { const [isChallengeChecked, setChallengeChecked] = useState(challenge); const [isImportantChecked, setImportantChecked] = useState(importance); const [currentDifficulty, setCurrentDifficulty] = useState(difficulty); @@ -28,7 +28,8 @@ function TaskDetailModal({ title, description, tags, difficulty, challenge, impo

- {}{title} + {} + {title}

{title}

@@ -45,13 +46,13 @@ function TaskDetailModal({ title, description, tags, difficulty, challenge, impo
-
+
@@ -144,5 +145,3 @@ function TaskDetailModal({ title, description, tags, difficulty, challenge, impo ); } - -export default TaskDetailModal; diff --git a/frontend/src/components/landingPage/LandingPage.jsx b/frontend/src/components/landingPage/LandingPage.jsx index 1fe0e1e..e26a44a 100644 --- a/frontend/src/components/landingPage/LandingPage.jsx +++ b/frontend/src/components/landingPage/LandingPage.jsx @@ -1,28 +1,19 @@ +import { FloatingParticles } from "../FlaotingParticles"; + export function LandingPage() { return (
-
-
- TurTask -
- + {/* Particles Container */} + + {/* Navbar */} +
+
-
-

+

Manage your task with{" "} TurTask @@ -33,21 +24,13 @@ export function LandingPage() {

-

- Lorem ipsum dolor sit amet consectetur adipisicing elit. Odio incidunt nam itaque sed eius modi error - totam sit illum. Voluptas doloribus asperiores quaerat aperiam. Quidem harum omnis beatae ipsum soluta! -

-
+

Unleash productivity with our personal task and project management.

+
diff --git a/frontend/src/components/navigations/IconSideNav.jsx b/frontend/src/components/navigations/IconSideNav.jsx index dc364f3..02cc1a0 100644 --- a/frontend/src/components/navigations/IconSideNav.jsx +++ b/frontend/src/components/navigations/IconSideNav.jsx @@ -1,9 +1,9 @@ import { useState } from "react"; -import { AiOutlineHome, AiOutlineSchedule, AiOutlineUnorderedList, AiOutlinePieChart } from "react-icons/ai"; +import { AiOutlineHome, AiOutlineSchedule, AiOutlineUnorderedList } from "react-icons/ai"; import { PiStepsDuotone } from "react-icons/pi"; import { IoSettingsOutline } from "react-icons/io5"; import { AnimatePresence, motion } from "framer-motion"; -import { Link, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; const menuItems = [ { id: 0, path: "/", icon: }, @@ -13,20 +13,12 @@ const menuItems = [ { id: 4, path: "/priority", icon: }, ]; -const IconSideNav = () => { - return ( -
- -
- ); -}; - -const SideNav = () => { +export const SideNav = () => { const [selected, setSelected] = useState(0); return (
); } -export default NavBar; diff --git a/frontend/src/components/ProfileUpdateComponent.jsx b/frontend/src/components/profile/ProfileUpdateComponent.jsx similarity index 95% rename from frontend/src/components/ProfileUpdateComponent.jsx rename to frontend/src/components/profile/ProfileUpdateComponent.jsx index 627ba9e..12f5e98 100644 --- a/frontend/src/components/ProfileUpdateComponent.jsx +++ b/frontend/src/components/profile/ProfileUpdateComponent.jsx @@ -1,7 +1,7 @@ import { useState, useRef } from "react"; -import { ApiUpdateUserProfile } from "../api/UserProfileApi"; +import { ApiUpdateUserProfile } from "src/api/UserProfileApi"; -function ProfileUpdateComponent() { +export function ProfileUpdateComponent() { const [file, setFile] = useState(null); const [username, setUsername] = useState(""); const [fullName, setFullName] = useState(""); @@ -100,5 +100,3 @@ function ProfileUpdateComponent() {
); } - -export default ProfileUpdateComponent; diff --git a/frontend/src/components/profilePage.jsx b/frontend/src/components/profile/profilePage.jsx similarity index 97% rename from frontend/src/components/profilePage.jsx rename to frontend/src/components/profile/profilePage.jsx index 35c260e..d61368a 100644 --- a/frontend/src/components/profilePage.jsx +++ b/frontend/src/components/profile/profilePage.jsx @@ -1,6 +1,6 @@ -import ProfileUpdateComponent from "./ProfileUpdateComponent"; +import { ProfileUpdateComponent } from "./ProfileUpdateComponent"; -function ProfileUpdatePage() { +export function ProfileUpdatePage() { return (
@@ -142,4 +142,3 @@ function ProfileUpdatePage() {
); } -export default ProfileUpdatePage; diff --git a/frontend/src/components/signup.jsx b/frontend/src/components/signup.jsx deleted file mode 100644 index e047627..0000000 --- a/frontend/src/components/signup.jsx +++ /dev/null @@ -1,115 +0,0 @@ -import { useState } from "react"; -import axiosapi from "../api/axiosapi"; -import TextField from "@material-ui/core/TextField"; -import Typography from "@material-ui/core/Typography"; -import CssBaseline from "@material-ui/core/CssBaseline"; -import Container from "@material-ui/core/Container"; -import Button from "@material-ui/core/Button"; -import { makeStyles } from "@material-ui/core/styles"; - -const useStyles = makeStyles((theme) => ({ - // Styles for various elements - paper: { - marginTop: theme.spacing(8), - display: "flex", - flexDirection: "column", - alignItems: "center", - }, - avatar: { - margin: theme.spacing(1), - backgroundColor: theme.palette.secondary.main, - }, - form: { - width: "100%", - marginTop: theme.spacing(1), - }, - submit: { - margin: theme.spacing(3, 0, 2), - }, -})); - -const Signup = () => { - const classes = useStyles(); - const [formData, setFormData] = useState({ - email: "", - username: "", - password: "", - }); - const [error, setError] = useState(null); - const [isSubmitting, setIsSubmitting] = useState(false); - - const handleSubmit = async (e) => { - e.preventDefault(); - setIsSubmitting(true); - setError(null); - - try { - axiosapi.createUser(formData); - } catch (error) { - console.error("Error creating user:", error); - setError("Registration failed. Please try again."); // Set an error message - } finally { - setIsSubmitting(false); - } - }; - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData({ ...formData, [name]: value }); - }; - - return ( - - -
- - Sign Up - -
- - - - - - {error && {error}} -
-
- ); -}; - -export default Signup; diff --git a/frontend/src/components/signup/Signup.jsx b/frontend/src/components/signup/Signup.jsx index dd25136..04c34b7 100644 --- a/frontend/src/components/signup/Signup.jsx +++ b/frontend/src/components/signup/Signup.jsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faGoogle, faGithub } from "@fortawesome/free-brands-svg-icons"; -function Signup() { +export function Signup() { return (
@@ -34,5 +34,3 @@ function Signup() {
); } - -export default Signup; diff --git a/frontend/src/components/testAuth.jsx b/frontend/src/components/testAuth.jsx deleted file mode 100644 index f57ea49..0000000 --- a/frontend/src/components/testAuth.jsx +++ /dev/null @@ -1,47 +0,0 @@ -import { useState, useEffect } from "react"; -import axiosapi from "../api/AuthenticationApi"; -import { Button } from "@mui/material"; -import { useNavigate } from "react-router-dom"; - -function TestAuth() { - let Navigate = useNavigate(); - - const [message, setMessage] = useState(""); - - useEffect(() => { - // Fetch the "hello" data from the server when the component mounts - axiosapi - .getGreeting() - .then((res) => { - console.log(res.data); - setMessage(res.data.user); - }) - .catch((err) => { - console.log(err); - setMessage(""); - }); - }, []); - - const logout = () => { - // Log out the user, clear tokens, and navigate to the "/testAuth" route - axiosapi.apiUserLogout(); - Navigate("/testAuth"); - }; - - return ( -
- {message !== "" && ( -
-

Login! Hello!

-

{message}

- -
- )} - {message === "" &&

Need to sign in, No authentication found

} -
- ); -} - -export default TestAuth; diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx index 8ca8296..9d45787 100644 --- a/frontend/src/main.jsx +++ b/frontend/src/main.jsx @@ -1,4 +1,4 @@ -import React, { Fragment } from "react"; +import { Fragment } from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import { GoogleOAuthProvider } from "@react-oauth/google"; diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 2adc53a..f715156 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -3,17 +3,14 @@ const defaultTheme = require("tailwindcss/defaultTheme"); export default { - content: [ - "./src/**/*.{js,jsx}", - "./node_modules/@tremor/**/*.{js,ts,jsx,tsx}", - ], + content: ["./src/**/*.{js,jsx}", "./node_modules/@tremor/**/*.{js,ts,jsx,tsx}"], theme: { extend: { fontFamily: { sans: ['"Proxima Nova"', ...defaultTheme.fontFamily.sans], }, - colors:{ + colors: { tremor: { brand: { faint: "#eff6ff", // blue-50 @@ -42,10 +39,9 @@ export default { strong: "#111827", // gray-900 inverted: "#ffffff", // white }, - }, }, - boxShadow:{ + boxShadow: { "tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)", "tremor-card": "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)", "tremor-dropdown": "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)", @@ -92,12 +88,7 @@ export default { /^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, }, ], - plugins: [ - require("daisyui"), - require("@tailwindcss/typography"), - require("daisyui"), - require("@headlessui/tailwindcss"), - ], + plugins: [require("daisyui"), require("@tailwindcss/typography"), require("@headlessui/tailwindcss")], daisyui: { themes: ["light", "night"], }, diff --git a/package.json b/package.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/package.json @@ -0,0 +1 @@ +{} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..2b9f188 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,5 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false