diff --git a/src/utils/Fetcher.jsx b/src/utils/Fetcher.jsx index 75c8190..5e168c6 100644 --- a/src/utils/Fetcher.jsx +++ b/src/utils/Fetcher.jsx @@ -65,6 +65,18 @@ const GetArchivedChores = () => { 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 => { return Fetch(`${API_URL}/chores/${id}`, { @@ -348,6 +360,7 @@ const DeleteLabel = id => { export { AcceptCircleMemberRequest, + ArchiveChore, CancelSubscription, createChore, CreateChore, @@ -384,6 +397,7 @@ export { SaveThing, signUp, SkipChore, + UnArchiveChore, UpdateChoreAssignee, UpdateChoreHistory, UpdateChorePriority, diff --git a/src/views/Chores/ChoreCard.jsx b/src/views/Chores/ChoreCard.jsx index 44e8c1f..641daf2 100644 --- a/src/views/Chores/ChoreCard.jsx +++ b/src/views/Chores/ChoreCard.jsx @@ -1,4 +1,5 @@ import { + Archive, CancelScheduleSend, Check, Delete, @@ -18,6 +19,7 @@ import { Report, SwitchAccessShortcut, TimesOneMobiledata, + Unarchive, Update, ViewCarousel, Webhook, @@ -43,8 +45,10 @@ import { useNavigate } from 'react-router-dom' import { API_URL } from '../../Config' import { UserContext } from '../../contexts/UserContext' import { + ArchiveChore, MarkChoreComplete, SkipChore, + UnArchiveChore, UpdateChoreAssignee, } from '../../utils/Fetcher' 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 = () => { setIsPendingCompletion(true) @@ -691,6 +719,12 @@ const ChoreCard = ({ View + + {chore.isActive ? : } + {chore.isActive ? 'Archive' : 'Unarchive'} + + + Delete diff --git a/src/views/Chores/MyChores.jsx b/src/views/Chores/MyChores.jsx index d56588a..8034f1d 100644 --- a/src/views/Chores/MyChores.jsx +++ b/src/views/Chores/MyChores.jsx @@ -172,19 +172,40 @@ const MyChores = () => { case 4: groupRaw['p4'].push(chore) 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 case 'labels': groupRaw = {} + var labels = {} chores.forEach(chore => { chore.labelsV2.forEach(label => { + labels[label.id] = label if (groupRaw[label.id] === undefined) { groupRaw[label.id] = [] } 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 } @@ -272,22 +293,39 @@ const MyChores = () => { } const handleChoreUpdated = (updatedChore, event) => { - const newChores = chores.map(chore => { + var newChores = chores.map(chore => { if (chore.id === updatedChore.id) { return updatedChore } return chore }) - const newFilteredChores = filteredChores.map(chore => { + var newFilteredChores = filteredChores.map(chore => { if (chore.id === updatedChore.id) { return updatedChore } 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) setFilteredChores(newFilteredChores) setChoreSections(sectionSorter('due_date', newChores)) + switch (event) { case 'completed': setSnackBarMessage('Completed') @@ -298,6 +336,12 @@ const MyChores = () => { case 'rescheduled': setSnackBarMessage('Rescheduled') break + case 'unarchive': + setSnackBarMessage('Unarchive') + break + case 'archive': + setSnackBarMessage('Archived') + break default: setSnackBarMessage('Updated') } diff --git a/src/views/Modals/Inputs/WriteNFCModal.jsx b/src/views/Modals/Inputs/WriteNFCModal.jsx index d71a2a3..2aad366 100644 --- a/src/views/Modals/Inputs/WriteNFCModal.jsx +++ b/src/views/Modals/Inputs/WriteNFCModal.jsx @@ -1,7 +1,9 @@ +import { CopyAll } from '@mui/icons-material' import { Box, Button, Checkbox, + Input, ListItem, Modal, ModalDialog, @@ -38,7 +40,9 @@ function WriteNFCModal({ config }) { } } else { 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 : 'Press the button below to write to NFC.'} + { + navigator.clipboard.writeText(getURL()) + alert('URL copied to clipboard!') + }} + /> + } + /> )} - - - - )