Files
donetick/src/App.jsx
Mo Tarbin 953c62cc66 feat: Enhance UserPoints component with improved filtering and layout
- 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.
2025-07-11 20:10:28 -04:00

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