From bb4ce79a095dd3bcc9800103f9f3b631e138d239 Mon Sep 17 00:00:00 2001 From: Hussain Omer Date: Fri, 27 Dec 2024 20:08:54 -0500 Subject: [PATCH] update tasks and project view --- .../Modal Management/Layout/List.js | 10 +- .../Modal Management/Layout/View.js | 3 +- .../Layout/__tests__/View.test.js | 20 +- .../Modal Management/Projects/ProjectForm.js | 2 +- .../Modal Management/Projects/ProjectView.js | 150 ++++++++++----- .../Modal Management/Tasks/TaskForm.js | 22 +-- .../Modal Management/Tasks/TaskView.js | 175 ++++++++++++------ client/src/integrations/ticktick/ticktick.js | 2 +- client/src/integrations/todoist/todoist.js | 2 +- client/src/services/xp/XPManager.js | 4 +- .../services/xp/__tests__/XPManager.test.js | 26 +-- client/src/utils/tasks/tasksUtils.js | 4 +- 12 files changed, 279 insertions(+), 141 deletions(-) diff --git a/client/src/components/Modal Management/Layout/List.js b/client/src/components/Modal Management/Layout/List.js index 713778c..d61122c 100644 --- a/client/src/components/Modal Management/Layout/List.js +++ b/client/src/components/Modal Management/Layout/List.js @@ -30,7 +30,7 @@ const TaskList = ({ difficulty: 5, importance: 5, deadline: null, - collaborative: false, + urgent: false, experience: 150 }); setQuickTaskInput(''); @@ -179,7 +179,7 @@ const TaskList = ({
- {task.deadline && ( -

Due date: {formatDeadline(task.deadline)}

+ + {/* Description Section */} + {task.desc && ( +
+

+ {task.desc} +

+
)} -

- Total Experience: {task.experience}xp - {isCompleted && task.earlyBonus > 0 && ( - - {` + ${task.earlyBonus}xp early bonus!`} - + + {/* Subtasks List */} +

+
+ {task.subtasks.map((subtask, index) => ( +
+
+ {!isCompleted && ( +
+ handleSubtaskToggle(index)} + /> +
+
+
+
+ )} + + {subtask.name} + +
+
+ ))} +
+
+ + {/* Task Info Footer */} +
+ {task.deadline && ( +
+ 📅 + + Due: {formatDeadline(task.deadline)} + {isOverdue(task.deadline) && !isCompleted && ( + + ({calculateOverduePenalty(task.deadline)}xp) + + )} + +
)} - {task.deadline && isOverdue(task.deadline) && ( - - {` ${calculateOverduePenalty(task.deadline)}xp`} +
+ + + {task.experience}xp + {isCompleted && task.earlyBonus > 0 && ( + + {` + ${task.earlyBonus}xp early bonus!`} + + )} - )} -

- +
+
+
); }; diff --git a/client/src/components/Modal Management/Tasks/TaskForm.js b/client/src/components/Modal Management/Tasks/TaskForm.js index b8554fc..0a884cc 100644 --- a/client/src/components/Modal Management/Tasks/TaskForm.js +++ b/client/src/components/Modal Management/Tasks/TaskForm.js @@ -10,7 +10,7 @@ const TaskForm = ({ addTask }) => { difficulty: 50, importance: 50, deadline: '', - collaborative: false, + urgent: false, label: '' }; @@ -34,12 +34,12 @@ const TaskForm = ({ addTask }) => { difficulty: formState.difficulty, importance: formState.importance, deadline: formState.deadline || null, - collaborative: formState.collaborative, + urgent: formState.urgent, label: formState.label || null, experience: calculateBaseXP( formState.difficulty, formState.importance, - formState.collaborative + formState.urgent ), completion: false }; @@ -64,8 +64,8 @@ const TaskForm = ({ addTask }) => { setSelectedDeadline(null); }; - const toggleCollaborative = () => { - updateFormState('collaborative', !formState.collaborative); + const toggleUrgent = () => { + updateFormState('urgent', !formState.urgent); }; const handleDeadlineClick = (days, buttonType) => { @@ -260,19 +260,19 @@ const TaskForm = ({ addTask }) => {
@@ -284,7 +284,7 @@ const TaskForm = ({ addTask }) => { {calculateBaseXP( formState.difficulty, formState.importance, - formState.collaborative + formState.urgent )}
diff --git a/client/src/components/Modal Management/Tasks/TaskView.js b/client/src/components/Modal Management/Tasks/TaskView.js index 68f9008..c5e8759 100644 --- a/client/src/components/Modal Management/Tasks/TaskView.js +++ b/client/src/components/Modal Management/Tasks/TaskView.js @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { formatDeadline, isOverdue, calculateOverduePenalty } from '../../../utils/tasks/tasksUtils'; -const TaskView = ({ task, isCompleted, showDescription, setShowDescription, isTextTruncated, textRef, nameOnly }) => { +const TaskView = ({ task, isCompleted, isTextTruncated, textRef, nameOnly }) => { const [showFullNameModal, setShowFullNameModal] = useState(false); const TaskName = () => ( @@ -85,41 +85,128 @@ const TaskView = ({ task, isCompleted, showDescription, setShowDescription, isTe return ( <> -
- - Details + {/* Description Section */} + {task.desc && ( +
+

+ {task.desc} +

+
+ )} + + {/* Metrics Section */} +
+
+
+ + + + + + {task.difficulty} + +
+
+ + Difficulty + + + {task.difficulty < 33 ? 'Easy' : task.difficulty < 66 ? 'Medium' : 'Hard'} + +
+
+ +
+
+ + + + + + {task.importance} + +
+
+ + Importance + + + {task.importance < 33 ? 'Low' : task.importance < 66 ? 'Medium' : 'High'} + +
+
-
- {task.desc.split('\n').map((line, index) => ( - - {line} -
-
- ))} + + {/* Task Info Footer */} +
+ {task.deadline && ( +
+ 📅 + + Due: {formatDeadline(task.deadline)} + {isOverdue(task.deadline) && !isCompleted && ( + + ({calculateOverduePenalty(task.deadline)}xp) + + )} + +
+ )} +
+ + + {task.experience}xp + {isCompleted && task.earlyBonus > 0 && ( + + +{task.earlyBonus}xp bonus + + )} + +
+
+ + {task.urgent ? '🚨 Urgent' : '⏱️ Regular'} + +
{showFullNameModal && ( @@ -153,24 +240,6 @@ const TaskView = ({ task, isCompleted, showDescription, setShowDescription, isTe
)} - - {task.deadline &&

Due date: {formatDeadline(task.deadline)}

} -

Difficulty: {task.difficulty}%

-

Importance: {task.importance}%

-

Type: {task.collaborative ? '👥 Collaborative' : '👤 Individual'}

-

- Experience given: {task.experience}xp - {isCompleted && task.earlyBonus > 0 && ( - - {` + ${task.earlyBonus}xp early bonus!`} - - )} - {task.deadline && isOverdue(task.deadline) && ( - - {` ${calculateOverduePenalty(task.deadline)}xp`} - - )} -

); }; diff --git a/client/src/integrations/ticktick/ticktick.js b/client/src/integrations/ticktick/ticktick.js index 78ca7c6..4f66740 100644 --- a/client/src/integrations/ticktick/ticktick.js +++ b/client/src/integrations/ticktick/ticktick.js @@ -13,7 +13,7 @@ export const importFromTickTick = async (addTask, setIsLoading) => { difficulty: 5, importance: 5, deadline: null, - collaborative: false, + urgent: false, experience: 150 })); addTask(tasksToAdd); diff --git a/client/src/integrations/todoist/todoist.js b/client/src/integrations/todoist/todoist.js index 6af604d..a67afb7 100644 --- a/client/src/integrations/todoist/todoist.js +++ b/client/src/integrations/todoist/todoist.js @@ -13,7 +13,7 @@ export const importFromTodoist = async (addTask, setIsLoading) => { difficulty: 5, importance: 5, deadline: null, - collaborative: false, + urgent: false, experience: 150 })); addTask(tasksToAdd); diff --git a/client/src/services/xp/XPManager.js b/client/src/services/xp/XPManager.js index b4eabfc..e7e4a25 100644 --- a/client/src/services/xp/XPManager.js +++ b/client/src/services/xp/XPManager.js @@ -94,10 +94,10 @@ const useXPManager = () => { }; }; - const calculateBaseXP = (difficulty, importance, collaborative = false) => { + const calculateBaseXP = (difficulty, importance, urgent = false) => { return (parseInt(difficulty) + parseInt(importance) + 20) * 5 + parseInt((parseInt(difficulty) * parseInt(importance)) / 20) + - (collaborative ? 150 : 0); + (urgent ? 150 : 0); }; const resetXP = () => { diff --git a/client/src/services/xp/__tests__/XPManager.test.js b/client/src/services/xp/__tests__/XPManager.test.js index 2e6a5ee..fb521b5 100644 --- a/client/src/services/xp/__tests__/XPManager.test.js +++ b/client/src/services/xp/__tests__/XPManager.test.js @@ -345,33 +345,33 @@ describe('Task Form XP Calculations', () => { const taskData = { difficulty: 50, importance: 50, - collaborative: false + urgent: false }; const expectedXP = (50 + 50 + 20) * 5 + parseInt((50 * 50) / 20); const calculatedXP = result.current.calculateBaseXP( taskData.difficulty, taskData.importance, - taskData.collaborative + taskData.urgent ); expect(calculatedXP).toBe(expectedXP); }); - test('adds collaborative bonus correctly', async () => { + test('adds urgent bonus correctly', async () => { const { result } = renderHook(() => useXPManager()); const taskData = { difficulty: 50, importance: 50, - collaborative: true + urgent: true }; const baseXP = (50 + 50 + 20) * 5 + parseInt((50 * 50) / 20); - const expectedXP = baseXP + 150; // Collaborative bonus + const expectedXP = baseXP + 150; // urgent bonus const calculatedXP = result.current.calculateBaseXP( taskData.difficulty, taskData.importance, - taskData.collaborative + taskData.urgent ); expect(calculatedXP).toBe(expectedXP); @@ -386,7 +386,7 @@ describe('Task Form XP Calculations', () => { // Max values calculation: // Base: (100 + 100 + 20) * 5 = 1100 // Difficulty/Importance: (100 * 100) / 20 = 500 - // Collaborative bonus: 150 + // urgent bonus: 150 // Total: 1100 + 500 + 150 = 1750 const maxXP = result.current.calculateBaseXP(100, 100, true); expect(maxXP).toBe(1750); @@ -474,25 +474,25 @@ describe('XP Calculation with Form Integration', () => { const taskConfig = { difficulty: 50, importance: 50, - collaborative: false + urgent: false }; const taskXP = result.current.calculateBaseXP( taskConfig.difficulty, taskConfig.importance, - taskConfig.collaborative + taskConfig.urgent ); const projectSubtaskXP = result.current.calculateBaseXP( taskConfig.difficulty, taskConfig.importance, - false // Projects don't have collaborative bonus per subtask + false // Projects don't have urgent bonus per subtask ); expect(taskXP).toBe(projectSubtaskXP); }); - test('correctly applies collaborative bonus only to tasks, not projects', async () => { + test('correctly applies urgent bonus only to tasks, not projects', async () => { const { result } = renderHook(() => useXPManager()); const config = { @@ -503,7 +503,7 @@ describe('XP Calculation with Form Integration', () => { const taskXP = result.current.calculateBaseXP( config.difficulty, config.importance, - true // Collaborative task + true // urgent task ); const projectXP = result.current.calculateBaseXP( @@ -512,6 +512,6 @@ describe('XP Calculation with Form Integration', () => { false // Project subtask ); - expect(taskXP).toBe(projectXP + 150); // Difference should be collaborative bonus + expect(taskXP).toBe(projectXP + 150); // Difference should be urgent bonus }); }); diff --git a/client/src/utils/tasks/tasksUtils.js b/client/src/utils/tasks/tasksUtils.js index 8698d36..a18aabc 100644 --- a/client/src/utils/tasks/tasksUtils.js +++ b/client/src/utils/tasks/tasksUtils.js @@ -41,7 +41,7 @@ export const calculateOverduePenalty = (deadline) => { * @param {string} [editForm.deadline] - Optional deadline in YYYY-MM-DD format * @param {number} editForm.difficulty - Task difficulty (0-100) * @param {number} editForm.importance - Task importance (0-100) - * @param {boolean} editForm.collaborative - Whether task is collaborative + * @param {boolean} editForm.urgent - Whether task is urgent * @param {string} [editForm.label] - Optional task label * @returns {Object} Updated task object with recalculated experience points */ @@ -51,7 +51,7 @@ export const handleEdit = (task, editForm) => { ...editForm, experience: (parseInt(editForm.difficulty) + parseInt(editForm.importance) + 20) * 5 + parseInt((parseInt(editForm.difficulty) * parseInt(editForm.importance)) / 20) + - (editForm.collaborative ? 150 : 0) + (editForm.urgent ? 150 : 0) }; };