archive and unarchive functionality to ChoreCard component
This commit is contained in:
commit
959e0fffa3
4 changed files with 115 additions and 9 deletions
|
@ -65,6 +65,18 @@ const GetArchivedChores = () => {
|
||||||
headers: HEADERS(),
|
headers: HEADERS(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const ArchiveChore = id => {
|
||||||
|
return Fetch(`${API_URL}/chores/${id}/archive`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: HEADERS(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const UnArchiveChore = id => {
|
||||||
|
return Fetch(`${API_URL}/chores/${id}/unarchive`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: HEADERS(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const GetChoreByID = id => {
|
const GetChoreByID = id => {
|
||||||
return Fetch(`${API_URL}/chores/${id}`, {
|
return Fetch(`${API_URL}/chores/${id}`, {
|
||||||
|
@ -348,6 +360,7 @@ const DeleteLabel = id => {
|
||||||
|
|
||||||
export {
|
export {
|
||||||
AcceptCircleMemberRequest,
|
AcceptCircleMemberRequest,
|
||||||
|
ArchiveChore,
|
||||||
CancelSubscription,
|
CancelSubscription,
|
||||||
createChore,
|
createChore,
|
||||||
CreateChore,
|
CreateChore,
|
||||||
|
@ -384,6 +397,7 @@ export {
|
||||||
SaveThing,
|
SaveThing,
|
||||||
signUp,
|
signUp,
|
||||||
SkipChore,
|
SkipChore,
|
||||||
|
UnArchiveChore,
|
||||||
UpdateChoreAssignee,
|
UpdateChoreAssignee,
|
||||||
UpdateChoreHistory,
|
UpdateChoreHistory,
|
||||||
UpdateChorePriority,
|
UpdateChorePriority,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
Archive,
|
||||||
CancelScheduleSend,
|
CancelScheduleSend,
|
||||||
Check,
|
Check,
|
||||||
Delete,
|
Delete,
|
||||||
|
@ -18,6 +19,7 @@ import {
|
||||||
Report,
|
Report,
|
||||||
SwitchAccessShortcut,
|
SwitchAccessShortcut,
|
||||||
TimesOneMobiledata,
|
TimesOneMobiledata,
|
||||||
|
Unarchive,
|
||||||
Update,
|
Update,
|
||||||
ViewCarousel,
|
ViewCarousel,
|
||||||
Webhook,
|
Webhook,
|
||||||
|
@ -43,8 +45,10 @@ import { useNavigate } from 'react-router-dom'
|
||||||
import { API_URL } from '../../Config'
|
import { API_URL } from '../../Config'
|
||||||
import { UserContext } from '../../contexts/UserContext'
|
import { UserContext } from '../../contexts/UserContext'
|
||||||
import {
|
import {
|
||||||
|
ArchiveChore,
|
||||||
MarkChoreComplete,
|
MarkChoreComplete,
|
||||||
SkipChore,
|
SkipChore,
|
||||||
|
UnArchiveChore,
|
||||||
UpdateChoreAssignee,
|
UpdateChoreAssignee,
|
||||||
} from '../../utils/Fetcher'
|
} from '../../utils/Fetcher'
|
||||||
import { getTextColorFromBackgroundColor } from '../../utils/LabelColors'
|
import { getTextColorFromBackgroundColor } from '../../utils/LabelColors'
|
||||||
|
@ -137,6 +141,30 @@ const ChoreCard = ({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const handleArchive = () => {
|
||||||
|
if (chore.isActive) {
|
||||||
|
ArchiveChore(chore.id).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
response.json().then(data => {
|
||||||
|
const newChore = { ...chore, isActive: false }
|
||||||
|
|
||||||
|
onChoreUpdate(newChore, 'archive')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
UnArchiveChore(chore.id).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
response.json().then(data => {
|
||||||
|
const newChore = { ...chore, isActive: true }
|
||||||
|
onChoreUpdate(newChore, 'unarchive')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMenuClose()
|
||||||
|
}
|
||||||
|
|
||||||
const handleTaskCompletion = () => {
|
const handleTaskCompletion = () => {
|
||||||
setIsPendingCompletion(true)
|
setIsPendingCompletion(true)
|
||||||
|
@ -691,6 +719,12 @@ const ChoreCard = ({
|
||||||
<ViewCarousel />
|
<ViewCarousel />
|
||||||
View
|
View
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem onClick={handleArchive} color='neutral'>
|
||||||
|
{chore.isActive ? <Archive /> : <Unarchive />}
|
||||||
|
{chore.isActive ? 'Archive' : 'Unarchive'}
|
||||||
|
</MenuItem>
|
||||||
|
<Divider />
|
||||||
|
|
||||||
<MenuItem onClick={handleDelete} color='danger'>
|
<MenuItem onClick={handleDelete} color='danger'>
|
||||||
<Delete />
|
<Delete />
|
||||||
Delete
|
Delete
|
||||||
|
|
|
@ -172,19 +172,40 @@ const MyChores = () => {
|
||||||
case 4:
|
case 4:
|
||||||
groupRaw['p4'].push(chore)
|
groupRaw['p4'].push(chore)
|
||||||
break
|
break
|
||||||
|
default:
|
||||||
|
groupRaw['no_priority'].push(chore)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
groups = [
|
||||||
|
{ name: 'Priority 1', content: groupRaw['p1'] },
|
||||||
|
{ name: 'Priority 2', content: groupRaw['p2'] },
|
||||||
|
{ name: 'Priority 3', content: groupRaw['p3'] },
|
||||||
|
{ name: 'Priority 4', content: groupRaw['p4'] },
|
||||||
|
{ name: 'No Priority', content: groupRaw['no_priority'] },
|
||||||
|
]
|
||||||
break
|
break
|
||||||
case 'labels':
|
case 'labels':
|
||||||
groupRaw = {}
|
groupRaw = {}
|
||||||
|
var labels = {}
|
||||||
chores.forEach(chore => {
|
chores.forEach(chore => {
|
||||||
chore.labelsV2.forEach(label => {
|
chore.labelsV2.forEach(label => {
|
||||||
|
labels[label.id] = label
|
||||||
if (groupRaw[label.id] === undefined) {
|
if (groupRaw[label.id] === undefined) {
|
||||||
groupRaw[label.id] = []
|
groupRaw[label.id] = []
|
||||||
}
|
}
|
||||||
groupRaw[label.id].push(chore)
|
groupRaw[label.id].push(chore)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
groups = Object.keys(groupRaw).map(key => {
|
||||||
|
return {
|
||||||
|
name: labels[key].name,
|
||||||
|
content: groupRaw[key],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
groups.sort((a, b) => {
|
||||||
|
a.name < b.name ? 1 : -1
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return groups
|
return groups
|
||||||
}
|
}
|
||||||
|
@ -272,22 +293,39 @@ const MyChores = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChoreUpdated = (updatedChore, event) => {
|
const handleChoreUpdated = (updatedChore, event) => {
|
||||||
const newChores = chores.map(chore => {
|
var newChores = chores.map(chore => {
|
||||||
if (chore.id === updatedChore.id) {
|
if (chore.id === updatedChore.id) {
|
||||||
return updatedChore
|
return updatedChore
|
||||||
}
|
}
|
||||||
return chore
|
return chore
|
||||||
})
|
})
|
||||||
|
|
||||||
const newFilteredChores = filteredChores.map(chore => {
|
var newFilteredChores = filteredChores.map(chore => {
|
||||||
if (chore.id === updatedChore.id) {
|
if (chore.id === updatedChore.id) {
|
||||||
return updatedChore
|
return updatedChore
|
||||||
}
|
}
|
||||||
return chore
|
return chore
|
||||||
})
|
})
|
||||||
|
if (event === 'archive') {
|
||||||
|
newChores = newChores.filter(chore => chore.id !== updatedChore.id)
|
||||||
|
newFilteredChores = newFilteredChores.filter(
|
||||||
|
chore => chore.id !== updatedChore.id,
|
||||||
|
)
|
||||||
|
if (archivedChores !== null) {
|
||||||
|
setArchivedChores([...archivedChores, updatedChore])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (event === 'unarchive') {
|
||||||
|
newChores.push(updatedChore)
|
||||||
|
newFilteredChores.push(updatedChore)
|
||||||
|
setArchivedChores(
|
||||||
|
archivedChores.filter(chore => chore.id !== updatedChore.id),
|
||||||
|
)
|
||||||
|
}
|
||||||
setChores(newChores)
|
setChores(newChores)
|
||||||
setFilteredChores(newFilteredChores)
|
setFilteredChores(newFilteredChores)
|
||||||
setChoreSections(sectionSorter('due_date', newChores))
|
setChoreSections(sectionSorter('due_date', newChores))
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case 'completed':
|
case 'completed':
|
||||||
setSnackBarMessage('Completed')
|
setSnackBarMessage('Completed')
|
||||||
|
@ -298,6 +336,12 @@ const MyChores = () => {
|
||||||
case 'rescheduled':
|
case 'rescheduled':
|
||||||
setSnackBarMessage('Rescheduled')
|
setSnackBarMessage('Rescheduled')
|
||||||
break
|
break
|
||||||
|
case 'unarchive':
|
||||||
|
setSnackBarMessage('Unarchive')
|
||||||
|
break
|
||||||
|
case 'archive':
|
||||||
|
setSnackBarMessage('Archived')
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
setSnackBarMessage('Updated')
|
setSnackBarMessage('Updated')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
import { CopyAll } from '@mui/icons-material'
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
Input,
|
||||||
ListItem,
|
ListItem,
|
||||||
Modal,
|
Modal,
|
||||||
ModalDialog,
|
ModalDialog,
|
||||||
|
@ -38,7 +40,9 @@ function WriteNFCModal({ config }) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setNfcStatus('error')
|
setNfcStatus('error')
|
||||||
setErrorMessage('NFC is not supported by this browser.')
|
setErrorMessage(
|
||||||
|
'NFC is not supported by this browser. You can still copy the URL and write it to an NFC tag using a compatible device.',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +77,22 @@ function WriteNFCModal({ config }) {
|
||||||
? errorMessage
|
? errorMessage
|
||||||
: 'Press the button below to write to NFC.'}
|
: 'Press the button below to write to NFC.'}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Input
|
||||||
|
value={getURL()}
|
||||||
|
fullWidth
|
||||||
|
readOnly
|
||||||
|
label='URL'
|
||||||
|
sx={{ mt: 1 }}
|
||||||
|
endDecorator={
|
||||||
|
<CopyAll
|
||||||
|
sx={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => {
|
||||||
|
navigator.clipboard.writeText(getURL())
|
||||||
|
alert('URL copied to clipboard!')
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={isAutoCompleteWhenScan}
|
checked={isAutoCompleteWhenScan}
|
||||||
|
@ -95,12 +115,6 @@ function WriteNFCModal({ config }) {
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box display={'flex'} justifyContent={'center'} mt={2}>
|
|
||||||
<Button onClick={handleClose} variant='outlined'>
|
|
||||||
Close
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue