- Updated UserPoints component to include a more user-friendly filter bar with enhanced styling. - Added a summary section to display the current filter context. - Refactored user selection and time period filtering logic for better clarity and performance. - Improved the layout of points cards and history sections for better visual hierarchy. - Integrated a bar chart for visual representation of points over time. - Updated redeem points functionality with better user feedback. feat: Add keyboard shortcuts in AddTaskModal for improved usability - Implemented keyboard shortcuts for adding descriptions, subtasks, and due dates. - Enhanced user experience by providing visual hints for keyboard shortcuts. - Refactored task creation logic to streamline the process. fix: Refactor ChoreActionMenu to handle mouse events and improve accessibility - Added mouse enter and leave event handlers for better interaction feedback. - Adjusted menu positioning for improved usability. refactor: Update RichTextEditor to support focus handling from parent components - Converted RichTextEditor to use forwardRef for better integration with parent components. - Exposed focus and blur methods for external control. - Improved image upload handling with better error management. fix: Adjust SubTask component to handle Enter key behavior correctly - Modified key event handling to prevent unintended task creation when holding meta or ctrl keys. - Added autoFocus prop to new task input for better user experience.
143 lines
3.4 KiB
JavaScript
143 lines
3.4 KiB
JavaScript
import NavBar from '@/views/components/NavBar'
|
|
import { Button, Typography, useColorScheme } from '@mui/joy'
|
|
import Tracker from '@openreplay/tracker'
|
|
import { useCallback, useEffect } from 'react'
|
|
import { Outlet, useNavigate } from 'react-router-dom'
|
|
import { useRegisterSW } from 'virtual:pwa-register/react'
|
|
import { registerCapacitorListeners } from './CapacitorListener'
|
|
import { ImpersonateUserProvider } from './contexts/ImpersonateUserContext'
|
|
import { AuthenticationProvider } from './service/AuthenticationService'
|
|
import { useNotification } from './service/NotificationProvider'
|
|
import { apiManager } from './utils/TokenManager'
|
|
import NetworkBanner from './views/components/NetworkBanner'
|
|
|
|
const add = className => {
|
|
document.getElementById('root').classList.add(className)
|
|
}
|
|
|
|
const remove = className => {
|
|
document.getElementById('root').classList.remove(className)
|
|
}
|
|
|
|
// TODO: Update the interval to at 60 minutes
|
|
const intervalMS = 5 * 60 * 1000 // 5 minutes
|
|
|
|
const AppContent = () => {
|
|
const { showNotification } = useNotification()
|
|
|
|
const {
|
|
needRefresh: [needRefresh, setNeedRefresh],
|
|
updateServiceWorker,
|
|
} = useRegisterSW({
|
|
onRegistered(r) {
|
|
console.log('SW Registered: ' + r)
|
|
r &&
|
|
setInterval(() => {
|
|
r.update()
|
|
}, intervalMS)
|
|
},
|
|
onRegisterError(error) {
|
|
console.log('SW registration error', error)
|
|
},
|
|
})
|
|
|
|
useEffect(() => {
|
|
if (needRefresh) {
|
|
showNotification({
|
|
type: 'custom',
|
|
component: (
|
|
<div>
|
|
<Typography level='body-md'>
|
|
A new version is now available. Click on reload button to update.
|
|
</Typography>
|
|
<Button
|
|
color='secondary'
|
|
size='small'
|
|
onClick={() => {
|
|
updateServiceWorker(true)
|
|
setNeedRefresh(false)
|
|
}}
|
|
sx={{ ml: 2 }}
|
|
>
|
|
Refresh
|
|
</Button>
|
|
</div>
|
|
),
|
|
snackbarProps: {
|
|
autoHideDuration: null, // Persistent until user action
|
|
},
|
|
})
|
|
}
|
|
}, [needRefresh, showNotification, updateServiceWorker, setNeedRefresh])
|
|
|
|
return (
|
|
<>
|
|
<ImpersonateUserProvider>
|
|
<NavBar />
|
|
<Outlet />
|
|
</ImpersonateUserProvider>
|
|
</>
|
|
)
|
|
}
|
|
|
|
function App() {
|
|
const navigate = useNavigate()
|
|
startApiManager(navigate)
|
|
startOpenReplay()
|
|
|
|
const { mode, systemMode } = useColorScheme()
|
|
|
|
const setThemeClass = useCallback(() => {
|
|
const value = JSON.parse(localStorage.getItem('themeMode')) || mode
|
|
|
|
if (value === 'system') {
|
|
if (systemMode === 'dark') {
|
|
return add('dark')
|
|
}
|
|
return remove('dark')
|
|
}
|
|
|
|
if (value === 'dark') {
|
|
return add('dark')
|
|
}
|
|
|
|
return remove('dark')
|
|
}, [mode, systemMode])
|
|
|
|
useEffect(() => {
|
|
setThemeClass()
|
|
}, [setThemeClass])
|
|
|
|
useEffect(() => {
|
|
registerCapacitorListeners()
|
|
}, [])
|
|
|
|
return (
|
|
<div className='min-h-screen'>
|
|
<NetworkBanner />
|
|
|
|
<AuthenticationProvider>
|
|
<AppContent />
|
|
</AuthenticationProvider>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const startOpenReplay = () => {
|
|
if (!import.meta.env.VITE_OPENREPLAY_PROJECT_KEY) return
|
|
const tracker = new Tracker({
|
|
projectKey: import.meta.env.VITE_OPENREPLAY_PROJECT_KEY,
|
|
})
|
|
|
|
tracker.start()
|
|
}
|
|
|
|
const startApiManager = navigate => {
|
|
apiManager.init()
|
|
apiManager.setNavigateToLogin(() => {
|
|
navigate('/login')
|
|
})
|
|
}
|
|
|
|
export default App
|