From 8fc0c15694e1621e492b1ed419eadf20f1e85465 Mon Sep 17 00:00:00 2001 From: James Birnie Date: Wed, 2 Apr 2025 15:24:50 -0700 Subject: [PATCH 1/2] Loading page --- frontend/react-app/package-lock.json | 66 +++++++++++++++++++ frontend/react-app/package.json | 2 + frontend/react-app/src/App.js | 2 + frontend/react-app/src/css/Loading.css | 6 ++ .../react-app/src/pages/AdminAllUsers.jsx | 3 +- frontend/react-app/src/pages/AdminPanel.jsx | 3 +- .../react-app/src/pages/CreateAccount.jsx | 3 +- .../react-app/src/pages/CreateTeamPage.jsx | 3 +- frontend/react-app/src/pages/EditTask.jsx | 3 +- .../react-app/src/pages/EditUserDetails.jsx | 3 +- frontend/react-app/src/pages/Home.jsx | 3 +- frontend/react-app/src/pages/Loading.jsx | 61 +++++++++++++++++ frontend/react-app/src/pages/MyTasks.jsx | 3 +- .../react-app/src/pages/Notifications.jsx | 3 +- frontend/react-app/src/pages/Profile.jsx | 3 +- frontend/react-app/src/pages/TeamTasks.jsx | 3 +- 16 files changed, 159 insertions(+), 11 deletions(-) create mode 100644 frontend/react-app/src/css/Loading.css create mode 100644 frontend/react-app/src/pages/Loading.jsx diff --git a/frontend/react-app/package-lock.json b/frontend/react-app/package-lock.json index 2b6c9c6c..ab21096f 100644 --- a/frontend/react-app/package-lock.json +++ b/frontend/react-app/package-lock.json @@ -13,8 +13,10 @@ "@testing-library/user-event": "^13.5.0", "ajv": "^8.17.1", "ajv-keywords": "^5.1.0", + "framer-motion": "^12.6.3", "jquery": "^3.7.1", "lucide-react": "^0.486.0", + "motion": "^12.6.3", "react": "^18.3.1", "react-cookie": "^7.2.2", "react-dom": "^18.3.1", @@ -8870,6 +8872,32 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/framer-motion": { + "version": "12.6.3", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.6.3.tgz", + "integrity": "sha512-2hsqknz23aloK85bzMc9nSR2/JP+fValQ459ZTVElFQ0xgwR2YqNjYSuDZdFBPOwVCt4Q9jgyTt6hg6sVOALzw==", + "dependencies": { + "motion-dom": "^12.6.3", + "motion-utils": "^12.6.3", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -13110,6 +13138,44 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/motion": { + "version": "12.6.3", + "resolved": "https://registry.npmjs.org/motion/-/motion-12.6.3.tgz", + "integrity": "sha512-zw/vqUgv5F5m9fkvOl/eCv2AF1+tkeZl3fu2uIlisIaip8sm5e0CouAl6GkdiRoF+G7s29CjqMdIyPMirwUGHA==", + "dependencies": { + "framer-motion": "^12.6.3", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/motion-dom": { + "version": "12.6.3", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.6.3.tgz", + "integrity": "sha512-gRY08RjcnzgFYLemUZ1lo/e9RkBxR+6d4BRvoeZDSeArG4XQXERSPapKl3LNQRu22Sndjf1h+iavgY0O4NrYqA==", + "dependencies": { + "motion-utils": "^12.6.3" + } + }, + "node_modules/motion-utils": { + "version": "12.6.3", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.6.3.tgz", + "integrity": "sha512-R/b3Ia2VxtTNZ4LTEO5pKYau1OUNHOuUfxuP0WFCTDYdHkeTBR9UtxR1cc8mDmKr8PEhmmfnTKGz3rSMjNRoRg==" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", diff --git a/frontend/react-app/package.json b/frontend/react-app/package.json index 41607bbd..888ca448 100644 --- a/frontend/react-app/package.json +++ b/frontend/react-app/package.json @@ -8,8 +8,10 @@ "@testing-library/user-event": "^13.5.0", "ajv": "^8.17.1", "ajv-keywords": "^5.1.0", + "framer-motion": "^12.6.3", "jquery": "^3.7.1", "lucide-react": "^0.486.0", + "motion": "^12.6.3", "react": "^18.3.1", "react-cookie": "^7.2.2", "react-dom": "^18.3.1", diff --git a/frontend/react-app/src/App.js b/frontend/react-app/src/App.js index 8307a604..ce4e3b66 100644 --- a/frontend/react-app/src/App.js +++ b/frontend/react-app/src/App.js @@ -18,6 +18,7 @@ import CreateTask from './pages/CreateTask'; import ChangePassword from './pages/ChangePassword'; import EditUserDetails from './pages/EditUserDetails'; import CreatTeamPage from './pages/CreateTeamPage'; +import Loading from './pages/Loading'; function App() { @@ -40,6 +41,7 @@ function App() { } urlReirect={"/login"}>}/> } urlReirect={"/home"}>}/> } urlReirect={"/home"}>}/> + }/> {/*Default path should be login, unless specified */} } /> diff --git a/frontend/react-app/src/css/Loading.css b/frontend/react-app/src/css/Loading.css new file mode 100644 index 00000000..ff27c5a6 --- /dev/null +++ b/frontend/react-app/src/css/Loading.css @@ -0,0 +1,6 @@ +.loadingContainer{ + display: flex; + justify-content: center; + align-items: center; + padding: 50px; +} \ No newline at end of file diff --git a/frontend/react-app/src/pages/AdminAllUsers.jsx b/frontend/react-app/src/pages/AdminAllUsers.jsx index a794b544..72408719 100644 --- a/frontend/react-app/src/pages/AdminAllUsers.jsx +++ b/frontend/react-app/src/pages/AdminAllUsers.jsx @@ -3,6 +3,7 @@ import Header from '../components/Header' import '../css/AdminAllUsers.css' import {useState, useEffect} from 'react' import { getTeams } from '../api/teamApi'; +import Loading from './Loading'; function AdminAllUsers(){ @@ -23,7 +24,7 @@ function AdminAllUsers(){ },[]) if(loading){ - return(
...loading
) + return() } return(
diff --git a/frontend/react-app/src/pages/AdminPanel.jsx b/frontend/react-app/src/pages/AdminPanel.jsx index 83d6ddd5..15ff9720 100644 --- a/frontend/react-app/src/pages/AdminPanel.jsx +++ b/frontend/react-app/src/pages/AdminPanel.jsx @@ -5,6 +5,7 @@ import '../css/AdminPanel.css' import {useNavigate} from 'react-router-dom' import { useEffect, useState } from "react"; import { getTeams } from "../api/teamApi"; +import Loading from "./Loading"; export default function AdminPanel(){ const { register, handleSubmit} = useForm(); @@ -38,7 +39,7 @@ export default function AdminPanel(){ },[]) if(loading){ - return(
...Loading
) + return() } return(
diff --git a/frontend/react-app/src/pages/CreateAccount.jsx b/frontend/react-app/src/pages/CreateAccount.jsx index 61ec9279..5cc2a339 100644 --- a/frontend/react-app/src/pages/CreateAccount.jsx +++ b/frontend/react-app/src/pages/CreateAccount.jsx @@ -3,6 +3,7 @@ import '../css/CreateAccount.css'; import Header from '../components/Header'; import CreateAccountForm from '../components/CreateAccountForm'; import { getTeams } from '../api/teamApi'; +import Loading from './Loading'; const CreateAccount = () => { const [loading, setLoading]= useState(true); @@ -31,7 +32,7 @@ const CreateAccount = () => { getAllTeams(); },[]) if(loading){ - return (
...Loading
) + return () } return (
diff --git a/frontend/react-app/src/pages/CreateTeamPage.jsx b/frontend/react-app/src/pages/CreateTeamPage.jsx index c15475c3..8d7b6367 100644 --- a/frontend/react-app/src/pages/CreateTeamPage.jsx +++ b/frontend/react-app/src/pages/CreateTeamPage.jsx @@ -4,6 +4,7 @@ import Header from '../components/Header'; import CreateTeamForm from '../components/CreateTeamForm'; import { getTeamMembers } from '../api/teamMemberAccountApi'; import { getAdmins } from '../api/adminApi'; +import Loading from './Loading'; export default function CreatTeamPage(){ const [loading, setLoading]= useState(true); @@ -32,7 +33,7 @@ export default function CreatTeamPage(){ getAllUsers(); },[]) if(loading){ - return (
...Loading
) + return () } return (
diff --git a/frontend/react-app/src/pages/EditTask.jsx b/frontend/react-app/src/pages/EditTask.jsx index f9b23625..b74577cd 100644 --- a/frontend/react-app/src/pages/EditTask.jsx +++ b/frontend/react-app/src/pages/EditTask.jsx @@ -4,6 +4,7 @@ import EditTaskForm from '../components/EditTaskForm' import Header from '../components/Header' import '../css/EditTask.css' import { getTeamMembers } from '../api/teamApi' +import Loading from './Loading' function EditTask(){ const location = useLocation() @@ -28,7 +29,7 @@ function EditTask(){ },[]); console.log("taskToEdit: ", taskToEdit) if(loading){ - return(
..Loading
) + return() } return(
diff --git a/frontend/react-app/src/pages/EditUserDetails.jsx b/frontend/react-app/src/pages/EditUserDetails.jsx index fd93f30d..49fdba2d 100644 --- a/frontend/react-app/src/pages/EditUserDetails.jsx +++ b/frontend/react-app/src/pages/EditUserDetails.jsx @@ -5,6 +5,7 @@ import { modifyAdminEmail, modifyAdminName } from "../api/adminAccountApi" import {getTeamMemberById, modifyTeamMemberEmail, modifyTeamMemberName } from "../api/teamMemberAccountApi" import {useForm} from 'react-hook-form' import { resetPassword } from "../api/adminApi" +import Loading from "./Loading" export default function EditUserDetails(){ const {register, handleSubmit} = useForm(); @@ -89,7 +90,7 @@ export default function EditUserDetails(){ },[accountToEdit]) if(loading){ return ( -
Loading...
+ ) } diff --git a/frontend/react-app/src/pages/Home.jsx b/frontend/react-app/src/pages/Home.jsx index 0d255c0f..47e597e6 100644 --- a/frontend/react-app/src/pages/Home.jsx +++ b/frontend/react-app/src/pages/Home.jsx @@ -7,6 +7,7 @@ import {Link} from 'react-router-dom' import fakeData from "../FakeData/fakeTaskData.json" import TaskList from '../components/TaskList'; import { getAssignedTasks } from "../api/teamMemberApi"; +import Loading from './Loading'; function setUpDataTasksToDo(obj){ let ansArr = [] @@ -115,7 +116,7 @@ const Home = () => { },[]) if(loading || loadingTasks){ - return (
Loading...
) + return () } return ( diff --git a/frontend/react-app/src/pages/Loading.jsx b/frontend/react-app/src/pages/Loading.jsx new file mode 100644 index 00000000..997ec874 --- /dev/null +++ b/frontend/react-app/src/pages/Loading.jsx @@ -0,0 +1,61 @@ +import '../css/Loading.css' +import { motion } from "framer-motion" +const circleStyle={ + top: '0', + left: '0', + display:'block', + width: '5rem', + height: '5rem', + border: '0.5rem solid #e9e9e9', + borderTop: '0.5rem solid #5d5d81', + borderRadius: '50%', + position: 'absoloute', + boxSizing: 'border-box' + +} +const spinTransition = { + repeat: Infinity, + duration: 1, + ease: "linear", + } +function Loading() { + return ( +
+ +
+ ) +} + +/** + * ============== Styles ================ + */ +function StyleSheet() { + return ( + + ) +} + +export default Loading diff --git a/frontend/react-app/src/pages/MyTasks.jsx b/frontend/react-app/src/pages/MyTasks.jsx index 031ea7ca..23fd25ef 100644 --- a/frontend/react-app/src/pages/MyTasks.jsx +++ b/frontend/react-app/src/pages/MyTasks.jsx @@ -8,6 +8,7 @@ import { getAssignedTasks } from "../api/teamMemberApi"; import { useCookies } from 'react-cookie'; import { useState, useEffect } from 'react'; import LockUnlockTask from "../components/LockUnlockTask"; +import Loading from "./Loading"; @@ -134,7 +135,7 @@ const headerAndAccessorsComplete = [ ...commonColumns ] if(loading){ - return (
Loading...
) + return () } const tasksToDoData = setUpData(tasksToDo); const tasksCompletedData = setUpDataCompleted(tasksToDo); diff --git a/frontend/react-app/src/pages/Notifications.jsx b/frontend/react-app/src/pages/Notifications.jsx index 1963b0e4..7fde3a58 100644 --- a/frontend/react-app/src/pages/Notifications.jsx +++ b/frontend/react-app/src/pages/Notifications.jsx @@ -4,6 +4,7 @@ import Notification from "../components/Notification"; import { getReadNotifications, getUnreadNotifications, markAsRead, markAsUnread, deleteNotification as deleteThisNotification} from '../api/notificationApi'; import { useCookies } from 'react-cookie'; import Header from '../components/Header' +import Loading from './Loading'; const Notifications = () => { const [cookies] = useCookies(['userInfo']) @@ -100,7 +101,7 @@ const Notifications = () => { ) ); if(loading){ - return(
...Loading
) + return() } return (
diff --git a/frontend/react-app/src/pages/Profile.jsx b/frontend/react-app/src/pages/Profile.jsx index 18205ff9..abda82d7 100644 --- a/frontend/react-app/src/pages/Profile.jsx +++ b/frontend/react-app/src/pages/Profile.jsx @@ -7,6 +7,7 @@ import { useCookies } from "react-cookie"; import { useEffect, useState } from "react"; import {getTeamMemberById} from '../api/teamMemberAccountApi' import { getTeamsForMember } from "../api/teamMemberApi"; +import Loading from "./Loading"; function Profile(){ const [cookies] = useCookies(['userInfo']); @@ -31,7 +32,7 @@ function Profile(){ getUserInfo(); },[]) if(loading){ - return (
...Loading
) + return () } console.log(userData) return ( diff --git a/frontend/react-app/src/pages/TeamTasks.jsx b/frontend/react-app/src/pages/TeamTasks.jsx index fd990d7f..f21ee50f 100644 --- a/frontend/react-app/src/pages/TeamTasks.jsx +++ b/frontend/react-app/src/pages/TeamTasks.jsx @@ -12,6 +12,7 @@ import LockUnlockTask from "../components/LockUnlockTask"; import DeleteTeamButton from "../components/DeleteTeamButton"; import { getAdmins } from "../api/adminApi"; import AddToTeam from "../components/AddToTeam"; +import Loading from "./Loading"; function getAssigneesNames(taskItem) { return taskItem.assignedMembers.map((member) => member.userName).join(", "); @@ -170,7 +171,7 @@ useEffect(()=>{ },[teamLead]) if(loadingNames || loadingTasks){ - return (
Loading...
) + return () } From 4b915f9583e8fd2dd3ee69e8fa0b1b80f7a5f173 Mon Sep 17 00:00:00 2001 From: James Birnie Date: Wed, 2 Apr 2025 15:32:22 -0700 Subject: [PATCH 2/2] Get rid of loading path --- frontend/react-app/src/App.js | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/react-app/src/App.js b/frontend/react-app/src/App.js index ce4e3b66..b81564de 100644 --- a/frontend/react-app/src/App.js +++ b/frontend/react-app/src/App.js @@ -41,7 +41,6 @@ function App() { } urlReirect={"/login"}>}/> } urlReirect={"/home"}>}/> } urlReirect={"/home"}>}/> - }/> {/*Default path should be login, unless specified */} } />