Files
donetick/src/views/Chores/components/ChoreModals.jsx
everysingletear 7d36090e46 i18n: extract the chore list and its modals (chores namespace)
Part of #145.

Twenty-three files across the task list zone: the list and card views,
sorting and grouping, multi-select and its toolbar and help sheet,
archived tasks, the assignee card, the chore action menu, the
nudge/NFC/photo modals, the rich text editor, the scan panel, the
notification templates and the keyboard-shortcut toasts.

Extends the existing `chores` namespace, so `src/i18n/config.js` is
untouched.

English only — no translations, no behaviour change. Every t() value is
checked against this branch's base: the string must appear
character-for-character in the code it replaces (247 call sites).

Two values are matched loosely and worth naming: archived.closeMultiSelect
in both the archived view and the toolbar. The base builds that tooltip as
`${size === 0 ? 'Close' : 'Clear'} multi-select (Esc)`, so only one branch
of the ternary exists contiguously in the source. Both keys hold exactly
what each branch renders; the tooltip is kept whole so a translator can
reorder it.

Rebased on current `develop` again after #215 and #216 landed — the
dictionary conflict was theirs, not the code's. No code file in this PR
was touched upstream in the meantime.
2026-08-15 09:03:28 +08:00

104 lines
2.8 KiB
JavaScript

import { Capacitor } from '@capacitor/core'
import { useTranslation } from 'react-i18next'
import DateModal from '../../Modals/Inputs/DateModal'
import DueDatePickerModal, {
combineDueDate,
splitDueDate,
} from '../../components/DueDatePickerModal'
import NudgeModal from '../../Modals/Inputs/NudgeModal'
import SelectModal from '../../Modals/Inputs/SelectModal'
import TextModal from '../../Modals/Inputs/TextModal'
import WriteNFCModal from '../../Modals/Inputs/WriteNFCModal'
const getNFCUrl = choreId =>
Capacitor.getPlatform() === 'android' || Capacitor.getPlatform() === 'ios'
? `donetick://chores/${choreId}`
: `${window.location.origin}/chores/${choreId}`
const ChoreModals = ({
activeModal,
modalChore,
membersData,
onChangeDueDate,
onCompleteWithPastDate,
onAssigneeChange,
onCompleteWithNote,
onNudge,
onClose,
}) => {
const { t } = useTranslation('chores')
return (
<>
{activeModal === 'changeDueDate' && modalChore && (
<DueDatePickerModal
open={true}
key={'changeDueDate' + modalChore.id}
title={t('modals.changeDueDate')}
{...splitDueDate(modalChore.nextDueDate)}
onClose={onClose}
onApply={parts =>
onChangeDueDate(combineDueDate(parts)?.toISOString() ?? null)
}
onRemove={() => onChangeDueDate(null)}
/>
)}
{activeModal === 'completeWithPastDate' && modalChore && (
<DateModal
isOpen={true}
key={'completedInPast' + modalChore.id}
current={modalChore.nextDueDate}
title={t('modals.completePast')}
onClose={onClose}
onSave={onCompleteWithPastDate}
/>
)}
{activeModal === 'changeAssignee' && modalChore && (
<SelectModal
isOpen={true}
options={membersData?.res || []}
displayKey='displayName'
title={t('modals.delegate')}
placeholder={t('modals.selectPerformer')}
onClose={onClose}
onSave={selected => onAssigneeChange(selected.id)}
/>
)}
{activeModal === 'completeWithNote' && modalChore && (
<TextModal
isOpen={true}
title={t('modals.addNote')}
onClose={onClose}
okText={t('modals.complete')}
onSave={onCompleteWithNote}
/>
)}
{activeModal === 'writeNFC' && modalChore && (
<WriteNFCModal
config={{
isOpen: true,
url: getNFCUrl(modalChore.id),
onClose: onClose,
}}
/>
)}
{activeModal === 'nudge' && modalChore && (
<NudgeModal
config={{
isOpen: true,
choreId: modalChore.id,
onClose: onClose,
onConfirm: onNudge,
}}
/>
)}
</>
)
}
export default ChoreModals