refactor NotificationSetting component to use SettingsLayout; remove NotificationSettings wrapper
This commit is contained in:
@@ -25,6 +25,7 @@ import {
|
||||
UpdateNotificationTarget,
|
||||
UpdateUserDetails,
|
||||
} from '../../utils/Fetcher'
|
||||
import SettingsLayout from './SettingsLayout'
|
||||
|
||||
const NotificationSetting = () => {
|
||||
const { showWarning } = useNotification()
|
||||
@@ -134,330 +135,334 @@ const NotificationSetting = () => {
|
||||
})
|
||||
}
|
||||
return (
|
||||
<div className='grid gap-4 py-4' id='notifications'>
|
||||
<Typography level='h3'>Device Notification</Typography>
|
||||
<Divider />
|
||||
<Typography level='body-md'>Manage your Device Notificaiton</Typography>
|
||||
<SettingsLayout title='Notification Settings'>
|
||||
<div className='grid gap-4 py-4' id='notifications'>
|
||||
<Typography level='h3'>Device Notification</Typography>
|
||||
<Divider />
|
||||
<Typography level='body-md'>Manage your Device Notificaiton</Typography>
|
||||
|
||||
<FormControl orientation='horizontal'>
|
||||
<Switch
|
||||
disabled={!Capacitor.isNativePlatform()}
|
||||
checked={deviceNotification}
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
if (deviceNotification === false) {
|
||||
LocalNotifications.requestPermissions().then(resp => {
|
||||
if (resp.display === 'granted') {
|
||||
setDeviceNotification(true)
|
||||
setNotificationPreferences({ granted: true })
|
||||
} else if (resp.display === 'denied') {
|
||||
showWarning({
|
||||
title: 'Notification Permission Denied',
|
||||
message:
|
||||
'You have denied notification permissions. You can enable them later in your device settings.',
|
||||
})
|
||||
setDeviceNotification(false)
|
||||
setNotificationPreferences({ granted: false })
|
||||
}
|
||||
})
|
||||
} else {
|
||||
setDeviceNotification(false)
|
||||
}
|
||||
}}
|
||||
color={deviceNotification ? 'success' : 'neutral'}
|
||||
variant={deviceNotification ? 'solid' : 'outlined'}
|
||||
slotProps={{
|
||||
endDecorator: {
|
||||
sx: {
|
||||
minWidth: 24,
|
||||
},
|
||||
},
|
||||
}}
|
||||
sx={{ mr: 2 }}
|
||||
/>
|
||||
<div>
|
||||
<FormLabel>Device Notification</FormLabel>
|
||||
<FormHelperText sx={{ mt: 0 }}>
|
||||
{Capacitor.isNativePlatform()
|
||||
? 'Receive notification on your device when a task is due'
|
||||
: 'This feature is only available on mobile devices'}{' '}
|
||||
</FormHelperText>
|
||||
</div>
|
||||
</FormControl>
|
||||
{deviceNotification && (
|
||||
<Card>
|
||||
{[
|
||||
{
|
||||
title: 'Due Date Notification',
|
||||
checked: dueNotification,
|
||||
set: setDueNotification,
|
||||
label: 'Notification when the task is due',
|
||||
property: 'dueNotification',
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
title: 'Pre-Due Date Notification',
|
||||
checked: preDueNotification,
|
||||
set: setPreDueNotification,
|
||||
label: 'Notification a few hours before the task is due',
|
||||
property: 'preDueNotification',
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
title: 'Overdue Notification',
|
||||
checked: naggingNotification,
|
||||
set: setNaggingNotification,
|
||||
label: 'Notification when the task is overdue',
|
||||
property: 'naggingNotification',
|
||||
disabled: false,
|
||||
},
|
||||
].map(item => (
|
||||
<FormControl
|
||||
key={item.property}
|
||||
orientation='horizontal'
|
||||
sx={{ width: 385, justifyContent: 'space-between' }}
|
||||
>
|
||||
<div>
|
||||
<FormLabel>{item.title}</FormLabel>
|
||||
<FormHelperText sx={{ mt: 0 }}>{item.label} </FormHelperText>
|
||||
</div>
|
||||
|
||||
<Switch
|
||||
checked={item.checked}
|
||||
disabled={item.disabled}
|
||||
onClick={() => {
|
||||
setNotificationPreferences({ [item.property]: !item.checked })
|
||||
item.set(!item.checked)
|
||||
}}
|
||||
color={item.checked ? 'success' : ''}
|
||||
variant='solid'
|
||||
endDecorator={item.checked ? 'On' : 'Off'}
|
||||
slotProps={{ endDecorator: { sx: { minWidth: 24 } } }}
|
||||
/>
|
||||
</FormControl>
|
||||
))}
|
||||
</Card>
|
||||
)}
|
||||
<FormControl
|
||||
orientation='horizontal'
|
||||
sx={{ width: 400, justifyContent: 'space-between' }}
|
||||
>
|
||||
<div>
|
||||
<FormLabel>Push Notifications</FormLabel>
|
||||
<FormHelperText sx={{ mt: 0 }}>
|
||||
{Capacitor.isNativePlatform()
|
||||
? 'Receive Nudges, Announcements, and Chore Assignments via Push Notifications'
|
||||
: 'This feature is only available on mobile devices'}{' '}
|
||||
</FormHelperText>
|
||||
</div>
|
||||
<Switch
|
||||
disabled={!Capacitor.isNativePlatform()}
|
||||
checked={pushNotification}
|
||||
onClick={async event => {
|
||||
event.preventDefault()
|
||||
if (pushNotification === false) {
|
||||
try {
|
||||
const resp = await PushNotifications.requestPermissions()
|
||||
console.log('user PushNotifications permission', resp)
|
||||
if (resp.receive === 'granted') {
|
||||
setPushNotification(true)
|
||||
setPushNotificationPreferences({ granted: true })
|
||||
// Register push notifications after permission is granted
|
||||
await registerPushNotifications()
|
||||
}
|
||||
if (resp.receive !== 'granted') {
|
||||
showWarning({
|
||||
title: 'Push Notification Permission Denied',
|
||||
message:
|
||||
'Push notifications have been disabled. You can enable them in your device settings if needed.',
|
||||
})
|
||||
setPushNotification(false)
|
||||
setPushNotificationPreferences({ granted: false })
|
||||
console.log('User denied permission', resp)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error setting up push notifications:', error)
|
||||
}
|
||||
} else {
|
||||
setPushNotification(false)
|
||||
}
|
||||
}}
|
||||
color={pushNotification ? 'success' : 'neutral'}
|
||||
variant={pushNotification ? 'solid' : 'outlined'}
|
||||
endDecorator={pushNotification ? 'On' : 'Off'}
|
||||
slotProps={{
|
||||
endDecorator: {
|
||||
sx: {
|
||||
minWidth: 24,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<Button
|
||||
variant='soft'
|
||||
color='primary'
|
||||
sx={{
|
||||
width: '210px',
|
||||
mb: 1,
|
||||
}}
|
||||
onClick={() => {
|
||||
// schedule a local notification in 5 seconds
|
||||
LocalNotifications.schedule({
|
||||
notifications: [
|
||||
{
|
||||
title: 'Task Reminder',
|
||||
body: 'You have a task due soon',
|
||||
id: 1,
|
||||
schedule: { at: new Date(Date.now() + 3000) },
|
||||
sound: null,
|
||||
attachments: null,
|
||||
actionTypeId: '',
|
||||
extra: null,
|
||||
},
|
||||
],
|
||||
})
|
||||
}}
|
||||
>
|
||||
Test Notification{' '}
|
||||
</Button>
|
||||
<Typography level='h3'>Custom Notification</Typography>
|
||||
<Divider />
|
||||
<Typography level='body-md'>
|
||||
Notificaiton through other platform like Telegram or Pushover
|
||||
</Typography>
|
||||
|
||||
<FormControl orientation='horizontal'>
|
||||
<Switch
|
||||
checked={Boolean(chatID !== 0)}
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
if (chatID !== 0) {
|
||||
setChatID(0)
|
||||
} else {
|
||||
setChatID('')
|
||||
UpdateUserDetails({
|
||||
chatID: Number(0),
|
||||
}).then(resp => {
|
||||
resp.json().then(data => {
|
||||
refetchUserProfile()
|
||||
<FormControl orientation='horizontal'>
|
||||
<Switch
|
||||
disabled={!Capacitor.isNativePlatform()}
|
||||
checked={deviceNotification}
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
if (deviceNotification === false) {
|
||||
LocalNotifications.requestPermissions().then(resp => {
|
||||
if (resp.display === 'granted') {
|
||||
setDeviceNotification(true)
|
||||
setNotificationPreferences({ granted: true })
|
||||
} else if (resp.display === 'denied') {
|
||||
showWarning({
|
||||
title: 'Notification Permission Denied',
|
||||
message:
|
||||
'You have denied notification permissions. You can enable them later in your device settings.',
|
||||
})
|
||||
setDeviceNotification(false)
|
||||
setNotificationPreferences({ granted: false })
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
setNotificationTarget('0')
|
||||
handleSave()
|
||||
}}
|
||||
color={chatID !== 0 ? 'success' : 'neutral'}
|
||||
variant={chatID !== 0 ? 'solid' : 'outlined'}
|
||||
slotProps={{
|
||||
endDecorator: {
|
||||
sx: {
|
||||
minWidth: 24,
|
||||
} else {
|
||||
setDeviceNotification(false)
|
||||
}
|
||||
}}
|
||||
color={deviceNotification ? 'success' : 'neutral'}
|
||||
variant={deviceNotification ? 'solid' : 'outlined'}
|
||||
slotProps={{
|
||||
endDecorator: {
|
||||
sx: {
|
||||
minWidth: 24,
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
sx={{ mr: 2 }}
|
||||
/>
|
||||
<div>
|
||||
<FormLabel>Custom Notification</FormLabel>
|
||||
<FormHelperText sx={{ mt: 0 }}>
|
||||
Receive notification on other platform
|
||||
</FormHelperText>
|
||||
</div>
|
||||
</FormControl>
|
||||
{chatID !== 0 && (
|
||||
<Box
|
||||
}}
|
||||
sx={{ mr: 2 }}
|
||||
/>
|
||||
<div>
|
||||
<FormLabel>Device Notification</FormLabel>
|
||||
<FormHelperText sx={{ mt: 0 }}>
|
||||
{Capacitor.isNativePlatform()
|
||||
? 'Receive notification on your device when a task is due'
|
||||
: 'This feature is only available on mobile devices'}{' '}
|
||||
</FormHelperText>
|
||||
</div>
|
||||
</FormControl>
|
||||
{deviceNotification && (
|
||||
<Card>
|
||||
{[
|
||||
{
|
||||
title: 'Due Date Notification',
|
||||
checked: dueNotification,
|
||||
set: setDueNotification,
|
||||
label: 'Notification when the task is due',
|
||||
property: 'dueNotification',
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
title: 'Pre-Due Date Notification',
|
||||
checked: preDueNotification,
|
||||
set: setPreDueNotification,
|
||||
label: 'Notification a few hours before the task is due',
|
||||
property: 'preDueNotification',
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
title: 'Overdue Notification',
|
||||
checked: naggingNotification,
|
||||
set: setNaggingNotification,
|
||||
label: 'Notification when the task is overdue',
|
||||
property: 'naggingNotification',
|
||||
disabled: false,
|
||||
},
|
||||
].map(item => (
|
||||
<FormControl
|
||||
key={item.property}
|
||||
orientation='horizontal'
|
||||
sx={{ width: 385, justifyContent: 'space-between' }}
|
||||
>
|
||||
<div>
|
||||
<FormLabel>{item.title}</FormLabel>
|
||||
<FormHelperText sx={{ mt: 0 }}>{item.label} </FormHelperText>
|
||||
</div>
|
||||
|
||||
<Switch
|
||||
checked={item.checked}
|
||||
disabled={item.disabled}
|
||||
onClick={() => {
|
||||
setNotificationPreferences({
|
||||
[item.property]: !item.checked,
|
||||
})
|
||||
item.set(!item.checked)
|
||||
}}
|
||||
color={item.checked ? 'success' : ''}
|
||||
variant='solid'
|
||||
endDecorator={item.checked ? 'On' : 'Off'}
|
||||
slotProps={{ endDecorator: { sx: { minWidth: 24 } } }}
|
||||
/>
|
||||
</FormControl>
|
||||
))}
|
||||
</Card>
|
||||
)}
|
||||
<FormControl
|
||||
orientation='horizontal'
|
||||
sx={{ width: 400, justifyContent: 'space-between' }}
|
||||
>
|
||||
<div>
|
||||
<FormLabel>Push Notifications</FormLabel>
|
||||
<FormHelperText sx={{ mt: 0 }}>
|
||||
{Capacitor.isNativePlatform()
|
||||
? 'Receive Nudges, Announcements, and Chore Assignments via Push Notifications'
|
||||
: 'This feature is only available on mobile devices'}{' '}
|
||||
</FormHelperText>
|
||||
</div>
|
||||
<Switch
|
||||
disabled={!Capacitor.isNativePlatform()}
|
||||
checked={pushNotification}
|
||||
onClick={async event => {
|
||||
event.preventDefault()
|
||||
if (pushNotification === false) {
|
||||
try {
|
||||
const resp = await PushNotifications.requestPermissions()
|
||||
console.log('user PushNotifications permission', resp)
|
||||
if (resp.receive === 'granted') {
|
||||
setPushNotification(true)
|
||||
setPushNotificationPreferences({ granted: true })
|
||||
// Register push notifications after permission is granted
|
||||
await registerPushNotifications()
|
||||
}
|
||||
if (resp.receive !== 'granted') {
|
||||
showWarning({
|
||||
title: 'Push Notification Permission Denied',
|
||||
message:
|
||||
'Push notifications have been disabled. You can enable them in your device settings if needed.',
|
||||
})
|
||||
setPushNotification(false)
|
||||
setPushNotificationPreferences({ granted: false })
|
||||
console.log('User denied permission', resp)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error setting up push notifications:', error)
|
||||
}
|
||||
} else {
|
||||
setPushNotification(false)
|
||||
}
|
||||
}}
|
||||
color={pushNotification ? 'success' : 'neutral'}
|
||||
variant={pushNotification ? 'solid' : 'outlined'}
|
||||
endDecorator={pushNotification ? 'On' : 'Off'}
|
||||
slotProps={{
|
||||
endDecorator: {
|
||||
sx: {
|
||||
minWidth: 24,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<Button
|
||||
variant='soft'
|
||||
color='primary'
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 2,
|
||||
width: '210px',
|
||||
mb: 1,
|
||||
}}
|
||||
onClick={() => {
|
||||
// schedule a local notification in 5 seconds
|
||||
LocalNotifications.schedule({
|
||||
notifications: [
|
||||
{
|
||||
title: 'Task Reminder',
|
||||
body: 'You have a task due soon',
|
||||
id: 1,
|
||||
schedule: { at: new Date(Date.now() + 3000) },
|
||||
sound: null,
|
||||
attachments: null,
|
||||
actionTypeId: '',
|
||||
extra: null,
|
||||
},
|
||||
],
|
||||
})
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
value={notificationTarget}
|
||||
sx={{ maxWidth: '200px' }}
|
||||
onChange={(e, selected) => setNotificationTarget(selected)}
|
||||
>
|
||||
<Option value='0'>None</Option>
|
||||
<Option value='1'>Telegram</Option>
|
||||
<Option value='2'>Pushover</Option>
|
||||
<Option value='3'>Webhooks</Option>
|
||||
</Select>
|
||||
{notificationTarget === '1' && (
|
||||
<>
|
||||
<Typography level='body-xs'>
|
||||
You need to initiate a message to the bot in order for the
|
||||
Telegram notification to work{' '}
|
||||
<a
|
||||
style={{
|
||||
textDecoration: 'underline',
|
||||
color: '#0891b2',
|
||||
}}
|
||||
href='https://t.me/DonetickBot'
|
||||
>
|
||||
Click here
|
||||
</a>{' '}
|
||||
to start a chat
|
||||
</Typography>
|
||||
Test Notification{' '}
|
||||
</Button>
|
||||
<Typography level='h3'>Custom Notification</Typography>
|
||||
<Divider />
|
||||
<Typography level='body-md'>
|
||||
Notificaiton through other platform like Telegram or Pushover
|
||||
</Typography>
|
||||
|
||||
<Typography level='body-sm'>Chat ID</Typography>
|
||||
|
||||
<Input
|
||||
value={chatID}
|
||||
onChange={e => setChatID(e.target.value)}
|
||||
placeholder='User ID / Chat ID'
|
||||
sx={{
|
||||
width: '200px',
|
||||
}}
|
||||
/>
|
||||
<Typography mt={0} level='body-xs'>
|
||||
If you don't know your Chat ID, start chat with userinfobot and
|
||||
it will send you your Chat ID.{' '}
|
||||
<a
|
||||
style={{
|
||||
textDecoration: 'underline',
|
||||
color: '#0891b2',
|
||||
}}
|
||||
href='https://t.me/userinfobot'
|
||||
>
|
||||
Click here
|
||||
</a>{' '}
|
||||
to start chat with userinfobot{' '}
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
{notificationTarget === '2' && (
|
||||
<>
|
||||
<Typography level='body-sm'>User key</Typography>
|
||||
<Input
|
||||
value={chatID}
|
||||
onChange={e => setChatID(e.target.value)}
|
||||
placeholder='User ID'
|
||||
sx={{
|
||||
width: '200px',
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{error && (
|
||||
<Typography color='warning' level='body-sm'>
|
||||
{error}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<Button
|
||||
sx={{
|
||||
width: '110px',
|
||||
mb: 1,
|
||||
<FormControl orientation='horizontal'>
|
||||
<Switch
|
||||
checked={Boolean(chatID !== 0)}
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
if (chatID !== 0) {
|
||||
setChatID(0)
|
||||
} else {
|
||||
setChatID('')
|
||||
UpdateUserDetails({
|
||||
chatID: Number(0),
|
||||
}).then(resp => {
|
||||
resp.json().then(data => {
|
||||
refetchUserProfile()
|
||||
})
|
||||
})
|
||||
}
|
||||
setNotificationTarget('0')
|
||||
handleSave()
|
||||
}}
|
||||
color={chatID !== 0 ? 'success' : 'neutral'}
|
||||
variant={chatID !== 0 ? 'solid' : 'outlined'}
|
||||
slotProps={{
|
||||
endDecorator: {
|
||||
sx: {
|
||||
minWidth: 24,
|
||||
},
|
||||
},
|
||||
}}
|
||||
sx={{ mr: 2 }}
|
||||
/>
|
||||
<div>
|
||||
<FormLabel>Custom Notification</FormLabel>
|
||||
<FormHelperText sx={{ mt: 0 }}>
|
||||
Receive notification on other platform
|
||||
</FormHelperText>
|
||||
</div>
|
||||
</FormControl>
|
||||
{chatID !== 0 && (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 2,
|
||||
}}
|
||||
onClick={handleSave}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</div>
|
||||
<Select
|
||||
value={notificationTarget}
|
||||
sx={{ maxWidth: '200px' }}
|
||||
onChange={(e, selected) => setNotificationTarget(selected)}
|
||||
>
|
||||
<Option value='0'>None</Option>
|
||||
<Option value='1'>Telegram</Option>
|
||||
<Option value='2'>Pushover</Option>
|
||||
<Option value='3'>Webhooks</Option>
|
||||
</Select>
|
||||
{notificationTarget === '1' && (
|
||||
<>
|
||||
<Typography level='body-xs'>
|
||||
You need to initiate a message to the bot in order for the
|
||||
Telegram notification to work{' '}
|
||||
<a
|
||||
style={{
|
||||
textDecoration: 'underline',
|
||||
color: '#0891b2',
|
||||
}}
|
||||
href='https://t.me/DonetickBot'
|
||||
>
|
||||
Click here
|
||||
</a>{' '}
|
||||
to start a chat
|
||||
</Typography>
|
||||
|
||||
<Typography level='body-sm'>Chat ID</Typography>
|
||||
|
||||
<Input
|
||||
value={chatID}
|
||||
onChange={e => setChatID(e.target.value)}
|
||||
placeholder='User ID / Chat ID'
|
||||
sx={{
|
||||
width: '200px',
|
||||
}}
|
||||
/>
|
||||
<Typography mt={0} level='body-xs'>
|
||||
If you don't know your Chat ID, start chat with userinfobot
|
||||
and it will send you your Chat ID.{' '}
|
||||
<a
|
||||
style={{
|
||||
textDecoration: 'underline',
|
||||
color: '#0891b2',
|
||||
}}
|
||||
href='https://t.me/userinfobot'
|
||||
>
|
||||
Click here
|
||||
</a>{' '}
|
||||
to start chat with userinfobot{' '}
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
{notificationTarget === '2' && (
|
||||
<>
|
||||
<Typography level='body-sm'>User key</Typography>
|
||||
<Input
|
||||
value={chatID}
|
||||
onChange={e => setChatID(e.target.value)}
|
||||
placeholder='User ID'
|
||||
sx={{
|
||||
width: '200px',
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{error && (
|
||||
<Typography color='warning' level='body-sm'>
|
||||
{error}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<Button
|
||||
sx={{
|
||||
width: '110px',
|
||||
mb: 1,
|
||||
}}
|
||||
onClick={handleSave}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</div>
|
||||
</SettingsLayout>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import NotificationSetting from './NotificationSetting'
|
||||
import SettingsLayout from './SettingsLayout'
|
||||
|
||||
const NotificationSettings = () => {
|
||||
return (
|
||||
<SettingsLayout title="Notification Settings">
|
||||
<NotificationSetting />
|
||||
</SettingsLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default NotificationSettings
|
||||
Reference in New Issue
Block a user