Skip to content

Commit

Permalink
refactor(updateGoal): Enable update goal name and/or category after set.
Browse files Browse the repository at this point in the history
  • Loading branch information
ZL-Asica committed Nov 8, 2024
1 parent 7341e76 commit efe3a21
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 80 deletions.
29 changes: 22 additions & 7 deletions src/components/Home/AddItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,33 @@
import CategoryPicker from '@/components/Home/CategoryPicker'
import { DateTimePicker } from '@/components/Home/DateTimePickers'
import AddIcon from '@mui/icons-material/Add'
import CheckIcon from '@mui/icons-material/Check'
import { IconButton, InputAdornment, TextField } from '@mui/material'
import { useState } from 'react'
import { useEffect, useState } from 'react'

const AddItem = ({ label, onAdd }) => {
const [inputValue, setInputValue] = useState('')
const [selectedCategory, setSelectedCategory] = useState('#000000') // For 'New Goal'
const AddItem = ({
label,
onAdd,
presetValue = '',
presetCategory = '#000000',
sx = {},
}) => {
const [inputValue, setInputValue] = useState(presetValue)
const [selectedCategory, setSelectedCategory] = useState(presetCategory) // For 'New Goal'
const [dueDate, setDueDate] = useState(null) // For 'New Task'

useEffect(() => {
if (presetValue) {
setInputValue(presetValue)
setSelectedCategory(presetCategory)
}
}, [presetValue, presetCategory])

const handleAdd = async () => {
if (inputValue.trim()) {
let attributes = null

if (label === 'New Goal') {
if (label === 'New Goal' || label === 'Edit Goal') {
attributes = selectedCategory
} else if (label === 'New Task') {
attributes = dueDate
Expand All @@ -30,7 +44,7 @@ const AddItem = ({ label, onAdd }) => {

// Conditionally render the category picker
const getStartAdornment = () => {
if (label === 'New Goal') {
if (label === 'New Goal' || label === 'Edit Goal') {
return (
<CategoryPicker
selectedCategory={selectedCategory}
Expand All @@ -49,6 +63,7 @@ const AddItem = ({ label, onAdd }) => {
display: 'flex',
alignItems: 'center',
gap: 2,
...sx,
}}
variant='outlined'
label={label}
Expand All @@ -67,7 +82,7 @@ const AddItem = ({ label, onAdd }) => {
onClick={handleAdd}
disabled={!inputValue.trim()}
>
<AddIcon />
{label === 'Edit Goal' ? <CheckIcon /> : <AddIcon />}
</IconButton>
</InputAdornment>
),
Expand Down
1 change: 0 additions & 1 deletion src/components/Home/CategoryPicker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ const CategoryPicker = ({ selectedCategory, setSelectedCategory }) => (
{colors.map((color, index) => (
<MenuItem
key={index}
className={'color-menu'}
value={color}
sx={{
display: 'inline-flex',
Expand Down
17 changes: 7 additions & 10 deletions src/hooks/useGoalsUpdater/addOperations.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,17 @@ export const addTask = async (
)
}

export const updateGoalCategory = async (
userContext,
goalIndex,
newCategory,
goals
) => {
goals[goalIndex] = {
...goals[goalIndex],
category: newCategory,
export const updateGoal = async (userContext, goalIndex, name, category) => {
const updatedGoals = [...userContext.user.goals]
updatedGoals[goalIndex] = {
...updatedGoals[goalIndex],
name,
category,
}

await updateGoalsAndStreak(
userContext,
goals,
updatedGoals,
'Goal category updated successfully.'
)
}
20 changes: 8 additions & 12 deletions src/hooks/useGoalsUpdater/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
// @ts-check

import { useUser } from '@/contexts/UserContext'
import {
addGoal,
addMicrogoal,
addTask,
updateGoalCategory,
} from './addOperations'
import { addGoal, addMicrogoal, addTask, updateGoal } from './addOperations'
import { deleteItem } from './deleteOperations'
import { toggleExpansion, toggleTaskCompletion } from './toggleOperations'

Expand All @@ -25,7 +20,7 @@ const useGoalsUpdater = () => {

/**
* Adds a new microgoal under a specified goal.
* @param {number} goalIndex - Index of the goal to add the microgoal to.
* @param {string} goalIndex - Index of the goal to add the microgoal to.
* @param {string} microGoalName - Name of the microgoal.
* @returns {Promise<void>}
*/
Expand All @@ -34,7 +29,7 @@ const useGoalsUpdater = () => {

/**
* Adds a new task under a specified microgoal.
* @param {number} goalIndex - Index of the goal.
* @param {string} goalIndex - Index of the goal.
* @param {number} microGoalIndex - Index of the microgoal.
* @param {string} taskName - Name of the task.
* @param {Date} dueDate - Due date for the task.
Expand All @@ -45,12 +40,13 @@ const useGoalsUpdater = () => {

/**
* Updates the category color for a specified goal.
* @param {number} goalIndex - Index of the goal.
* @param {string} newCategory - New HEX color code for the goal category.
* @param {string} goalIndex - Index of the goal.
* @param {string} name - New name for the goal.
* @param {string} category - New category color for the goal.
* @returns {Promise<void>}
*/
updateGoalCategory: (goalIndex, newCategory) =>
updateGoalCategory(userContext, goalIndex, newCategory, user.goals),
updateGoal: (goalIndex, name, category) =>
updateGoal(userContext, goalIndex, name, category),

/**
* Deletes a specified goal, microgoal, or task.
Expand Down
50 changes: 45 additions & 5 deletions src/pages/GoalDetails.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
// @ts-check

import AddItem from '@/components/Home/AddItem'
import MicroGoal from '@/components/Home/MicroGoal'
import ProgressIndicator from '@/components/Home/ProgressIndicator'
import { useUser } from '@/contexts/UserContext'
import useGoalsUpdater from '@/hooks/useGoalsUpdater'
import { calculateProgress } from '@/utils/calculateProgress'
import { Box, List, Paper, Typography } from '@mui/material'
import EditIcon from '@mui/icons-material/Edit'
import {
Box,
Collapse,
darken,
IconButton,
List,
Paper,
Typography,
} from '@mui/material'
import { useState } from 'react'
import { useParams } from 'react-router-dom'

const GoalDetails = () => {
const [editGoalInput, setEditGoalInput] = useState(false)
const { macroGoalIndex } = useParams()
const { user } = useUser()
const { addMicrogoal } = useGoalsUpdater()
const { addMicrogoal, updateGoal } = useGoalsUpdater()

const macroGoal = user.goals[macroGoalIndex]
const categoryColor = macroGoal.category || '#000'

// @ts-ignore
const progress = calculateProgress(macroGoal.microgoals)

return (
Expand All @@ -24,15 +40,38 @@ const GoalDetails = () => {
mb: 3,
borderRadius: 2,
border: '2px solid',
borderColor: macroGoal.category ? macroGoal.category : '#000',
borderColor: categoryColor,
}}
>
<Box display='flex' alignItems='center'>
<Box
display='flex'
alignItems='center'
onClick={() => setEditGoalInput(!editGoalInput)} // Click to edit goal name
>
<ProgressIndicator value={progress} size={50} thickness={4} />
<Typography variant='h5' sx={{ ml: 2 }}>
<Typography variant='h5' sx={{ ml: 2, flexGrow: 1 }}>
{macroGoal.name}
</Typography>
<IconButton
aria-label='Edit Goal'
onClick={() => setEditGoalInput(!editGoalInput)}
sx={{ color: darken(categoryColor, 0.3) }}
>
<EditIcon />
</IconButton>
</Box>
<Collapse in={editGoalInput} timeout='auto' unmountOnExit>
<AddItem
label='Edit Goal'
onAdd={(name, category) => {
updateGoal(macroGoalIndex, name, category)
setEditGoalInput(false)
}}
presetValue={macroGoal.name}
presetCategory={categoryColor}
sx={{ mt: 2 }}
/>
</Collapse>
</Paper>

<AddItem
Expand All @@ -41,6 +80,7 @@ const GoalDetails = () => {
/>

<List sx={{ mt: 3 }}>
{/* @ts-ignore */}
{macroGoal.microgoals.map((microGoal, microGoalIndex) => (
<MicroGoal
key={microGoalIndex}
Expand Down
46 changes: 1 addition & 45 deletions src/pages/Home.jsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,12 @@
import AddItem from '@/components/Home/AddItem'
import CategoryPicker from '@/components/Home/CategoryPicker'
import MacroGoal from '@/components/Home/MacroGoal'
import { useUser } from '@/contexts/UserContext'
import useGoalsUpdater from '@/hooks/useGoalsUpdater'
import { Box } from '@mui/material'
import { useEffect, useState } from 'react'

const Home = () => {
const { user } = useUser()
const { addGoal, updateGoalCategory } = useGoalsUpdater()
const [editingCategoryIndex, setEditingCategoryIndex] = useState(null)

// Function to handle click outside of CategoryPicker, goal container, color menu
const handleClickOutside = (event) => {
if (
!event.target.closest('.category-picker') &&
!event.target.closest('.goal-container') &&
!event.target.closest('.color-menu')
) {
setEditingCategoryIndex(null)
}
}

useEffect(() => {
document.addEventListener('mousedown', handleClickOutside)
return () => {
document.removeEventListener('mousedown', handleClickOutside)
}
}, [])

const handleCategoryClick = (index) => {
setEditingCategoryIndex(index)
}

const handleCategoryChange = (newCategory) => {
if (editingCategoryIndex !== null) {
updateGoalCategory(editingCategoryIndex, newCategory)
setEditingCategoryIndex(null)
}
}
const { addGoal } = useGoalsUpdater()

return (
<Box sx={{ maxWidth: 800, margin: 'auto', padding: 3 }}>
Expand All @@ -49,25 +17,13 @@ const Home = () => {
{user.goals.map((goal, index) => (
<Box
key={index}
className='goal-container'
sx={{
borderLeft: `5px solid ${goal.category || '#000'}`,
paddingLeft: 2,
mb: 2,
}}
onClick={() => handleCategoryClick(index)}
>
<MacroGoal macroGoal={goal} macroGoalIndex={index} />

{/* Conditionally render CategoryPicker when category is being edited */}
{editingCategoryIndex === index && (
<div className='category-picker'>
<CategoryPicker
selectedCategory={goal.category}
setSelectedCategory={handleCategoryChange}
/>
</div>
)}
</Box>
))}
</Box>
Expand Down

0 comments on commit efe3a21

Please sign in to comment.