diff --git a/package.json b/package.json
index c025855..95048d1 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "donetick",
"private": true,
- "version": "0.1.79",
+ "version": "0.1.80",
"type": "module",
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
diff --git a/src/views/ChoreEdit/ChoreView.jsx b/src/views/ChoreEdit/ChoreView.jsx
index 8b2d2ed..3347ed7 100644
--- a/src/views/ChoreEdit/ChoreView.jsx
+++ b/src/views/ChoreEdit/ChoreView.jsx
@@ -103,12 +103,13 @@ const ChoreView = () => {
}
}, [chore, performers])
const handleUpdatePriority = priority => {
- if (priority.value === 0) {
- setChorePriority(null)
- } else {
- setChorePriority(priority)
- }
- UpdateChorePriority(choreId, priority.value)
+ UpdateChorePriority(choreId, priority.value).then(response => {
+ if (response.ok) {
+ response.json().then(data => {
+ setChorePriority(priority)
+ })
+ }
+ })
}
const generateInfoCards = chore => {
const cards = [
@@ -265,7 +266,6 @@ const ChoreView = () => {
? `Due at ${moment(chore.nextDueDate).format('MM/DD/YYYY hh:mm A')}`
: 'N/A'}
- {/* show each label : */}
{chore?.labelsV2?.map((label, index) => (
{
const [activeUserId, setActiveUserId] = React.useState(0)
const [isChangeDueDateModalOpen, setIsChangeDueDateModalOpen] =
@@ -504,6 +506,13 @@ const ChoreCard = ({
? 'warning'
: 'neutral'
}
+ startDecorator={
+ Priorities.find(p => p.value === chore.priority)?.icon
+ }
+ onClick={e => {
+ e.stopPropagation()
+ onChipClick({ priority: chore.priority })
+ }}
>
P{chore.priority}
@@ -512,16 +521,22 @@ const ChoreCard = ({
return (
{
+ // e.stopPropagation()
+ // onChipClick({ label: l })
+ // }}
// startDecorator={getIconForLabel(label)}
>
@@ -719,7 +734,9 @@ const ChoreCard = ({
handleAssigneChange(selected.id)
}}
/>
-
+ {confirmModelConfig?.isOpen && (
+
+ )}
{
+ const [anchorEl, setAnchorEl] = useState(null)
+ const menuRef = useRef(null)
+
+ const handleMenuOpen = event => {
+ setAnchorEl(event.currentTarget)
+ }
+
+ const handleMenuClose = () => {
+ setAnchorEl(null)
+ }
+ useEffect(() => {
+ document.addEventListener('mousedown', handleMenuOutsideClick)
+ return () => {
+ document.removeEventListener('mousedown', handleMenuOutsideClick)
+ }
+ }, [anchorEl])
+
+ const handleMenuOutsideClick = event => {
+ if (menuRef.current && !menuRef.current.contains(event.target)) {
+ handleMenuClose()
+ }
+ }
+
+ return (
+ <>
+
+ {icon}
+
+
+
+ >
+ )
+}
+export default IconButtonWithMenu
diff --git a/src/views/Chores/MyChores.jsx b/src/views/Chores/MyChores.jsx
index cc7ab58..eb93df6 100644
--- a/src/views/Chores/MyChores.jsx
+++ b/src/views/Chores/MyChores.jsx
@@ -3,10 +3,12 @@ import {
CancelRounded,
EditCalendar,
FilterAlt,
- FilterAltOff,
+ PriorityHigh,
+ Style,
} from '@mui/icons-material'
import {
Box,
+ Button,
Chip,
Container,
IconButton,
@@ -23,9 +25,11 @@ import { useNavigate } from 'react-router-dom'
import { UserContext } from '../../contexts/UserContext'
import { useChores } from '../../queries/ChoreQueries'
import { GetAllUsers, GetUserProfile } from '../../utils/Fetcher'
+import Priorities from '../../utils/Priorities'
import LoadingComponent from '../components/Loading'
import { useLabels } from '../Labels/LabelQueries'
import ChoreCard from './ChoreCard'
+import IconButtonWithMenu from './IconButtonWithMenu'
const MyChores = () => {
const { userProfile, setUserProfile } = useContext(UserContext)
@@ -122,6 +126,28 @@ const MyChores = () => {
const handleFilterMenuClose = () => {
setAnchorEl(null)
}
+
+ const handleLabelFiltering = chipClicked => {
+ console.log('chipClicked', chipClicked)
+
+ if (chipClicked.label) {
+ const label = chipClicked.label
+ const labelFiltered = [...chores].filter(chore =>
+ chore.labelsV2.some(l => l.id === label.id),
+ )
+ console.log('labelFiltered', labelFiltered)
+ setFilteredChores(labelFiltered)
+ setSelectedFilter('Label: ' + label.name)
+ } else if (chipClicked.priority) {
+ const priority = chipClicked.priority
+ const priorityFiltered = chores.filter(
+ chore => chore.priority === priority,
+ )
+ setFilteredChores(priorityFiltered)
+ setSelectedFilter('Priority: ' + priority)
+ }
+ }
+
const handleChoreUpdated = (updatedChore, event) => {
const newChores = chores.map(chore => {
if (chore.id === updatedChore.id) {
@@ -175,13 +201,16 @@ const MyChores = () => {
chores.map(c => ({
...c,
raw_label: c.labelsV2
- .map(l => userLabels.find(x => (x.id = l.id)).name)
+ .map(l => userLabels.find(x => x.id === l.id).name)
.join(' '),
})),
searchOptions,
)
const handleSearchChange = e => {
+ if (selectedFilter !== 'All') {
+ setSelectedFilter('All')
+ }
const search = e.target.value
if (search === '') {
setFilteredChores(chores)
@@ -209,7 +238,6 @@ const MyChores = () => {
My Chores
*/}
{/* */}
-
{/* Search box to filter */}
{
justifyContent: 'space-between',
alignContent: 'center',
alignItems: 'center',
- gap: 1,
+ gap: 0.5,
}}
>
{
)
}
/>
+ }
+ options={Priorities}
+ selectedItem={selectedFilter}
+ onItemSelect={selected => {
+ handleLabelFiltering({ priority: selected.value })
+ }}
+ mouseClickHandler={handleMenuOutsideClick}
+ isActive={selectedFilter.startsWith('Priority: ')}
+ />
+ }
+ options={userLabels}
+ selectedItem={selectedFilter}
+ onItemSelect={selected => {
+ handleLabelFiltering({ label: selected })
+ }}
+ isActive={selectedFilter.startsWith('Label: ')}
+ mouseClickHandler={handleMenuOutsideClick}
+ useChips
+ />
+
{
borderRadius: 24,
}}
>
- {selectedFilter && selectedFilter != 'All' ? (
-
- ) : (
-
- )}
+
- {/* */}
-
))}
+ {selectedFilter.startsWith('Label: ') ||
+ (selectedFilter.startsWith('Priority: ') && (
+
+ ))}
-
+ {selectedFilter !== 'All' && (
+ {
+ setFilteredChores(chores)
+ setSelectedFilter('All')
+ }}
+ endDecorator={}
+ onClick={() => {
+ setFilteredChores(chores)
+ setSelectedFilter('All')
+ }}
+ >
+ Current Filter: {selectedFilter}
+
+ )}
{/* */}
{filteredChores.length === 0 && (
{
Nothing scheduled
+ {chores.length > 0 && (
+ <>
+
+ >
+ )}
)}
@@ -346,6 +425,7 @@ const MyChores = () => {
onChoreRemove={handleChoreDeleted}
performers={performers}
userLabels={userLabels}
+ onChipClick={handleLabelFiltering}
/>
))}
@@ -421,6 +501,13 @@ const FILTERS = {
)
})
},
+ 'Due Later': function (chores) {
+ return chores.filter(chore => {
+ return (
+ new Date(chore.nextDueDate) > new Date(Date.now() + 24 * 60 * 60 * 1000)
+ )
+ })
+ },
'Created By Me': function (chores, userID) {
return chores.filter(chore => {
return chore.createdBy === userID
diff --git a/src/views/Labels/LabelView.jsx b/src/views/Labels/LabelView.jsx
index 9dd442a..62e699b 100644
--- a/src/views/Labels/LabelView.jsx
+++ b/src/views/Labels/LabelView.jsx
@@ -15,33 +15,55 @@ import { useLabels } from './LabelQueries'
// import { useMutation, useQueryClient } from '@tanstack/react-query'
import { Add } from '@mui/icons-material'
import { useQueryClient } from 'react-query'
+import { useNavigate } from 'react-router-dom'
import { DeleteLabel } from '../../utils/Fetcher'
+import ConfirmationModal from '../Modals/Inputs/ConfirmationModal'
const LabelView = () => {
const { data: labels, isLabelsLoading, isError } = useLabels()
const [userLabels, setUserLabels] = useState([labels])
const [modalOpen, setModalOpen] = useState(false)
- const [currentLabel, setCurrentLabel] = useState(null) // Label being edited or null for new label
+ const [currentLabel, setCurrentLabel] = useState(null)
const queryClient = useQueryClient()
+ const [confirmationModel, setConfirmationModel] = useState({})
+ const Navigate = useNavigate()
const handleAddLabel = () => {
- setCurrentLabel(null) // Adding a new label
+ setCurrentLabel(null)
setModalOpen(true)
}
const handleEditLabel = label => {
- setCurrentLabel(label) // Editing an existing label
+ setCurrentLabel(label)
setModalOpen(true)
}
+ const handleDeleteClicked = id => {
+ setConfirmationModel({
+ isOpen: true,
+ title: 'Delete Label',
+
+ message:
+ 'Are you sure you want to delete this label? This will remove the label from all tasks.',
+
+ confirmText: 'Delete',
+ color: 'danger',
+ cancelText: 'Cancel',
+ onClose: confirmed => {
+ if (confirmed) {
+ handleDeleteLabel(id)
+ }
+ setConfirmationModel({})
+ },
+ })
+ }
+
const handleDeleteLabel = id => {
DeleteLabel(id).then(res => {
- // Invalidate and refetch labels after deleting a label
const updatedLabels = userLabels.filter(label => label.id !== id)
setUserLabels(updatedLabels)
queryClient.invalidateQueries('labels')
})
- // Implement deletion logic here
}
const handleSaveLabel = newOrUpdatedLabel => {
@@ -92,7 +114,13 @@ const LabelView = () => {
{userLabels.map(label => (
- | {label.name} |
+ {
+ Navigate('/my/chores', { state: { label: label.id } })
+ }}
+ >
+ {label.name}
+ |
{
handleDeleteLabel(label.id)}
+ onClick={() => handleDeleteClicked(label.id)}
color='danger'
>
@@ -151,7 +179,7 @@ const LabelView = () => {
position: 'fixed',
bottom: 0,
left: 10,
- p: 2, // padding
+ p: 2,
display: 'flex',
justifyContent: 'flex-end',
gap: 2,
@@ -171,6 +199,7 @@ const LabelView = () => {
+
)
}
diff --git a/src/views/Modals/Inputs/ConfirmationModal.jsx b/src/views/Modals/Inputs/ConfirmationModal.jsx
index 10f9bee..882522e 100644
--- a/src/views/Modals/Inputs/ConfirmationModal.jsx
+++ b/src/views/Modals/Inputs/ConfirmationModal.jsx
@@ -24,6 +24,7 @@ function ConfirmationModal({ config }) {
}}
fullWidth
sx={{ mr: 1 }}
+ color={config.color ? config.color : 'primary'}
>
{config?.confirmText}
|