Merge branch 'dev'

This commit is contained in:
Mo Tarbin
2025-07-14 02:05:52 -04:00
6 changed files with 65 additions and 14 deletions

View File

@@ -1,4 +1,5 @@
import { Modal, ModalDialog, ModalOverflow } from '@mui/joy'
import Z_INDEX from '../../constants/zIndex'
/**
* FadeModal component with consistent fade-in/out animations
@@ -18,8 +19,10 @@ const FadeModal = ({
open={open}
onClose={onClose}
sx={{
zIndex: Z_INDEX.MODAL_BACKDROP,
'& .MuiModal-backdrop': {
backdropFilter: backdropBlur ? 'blur(3px)' : 'none',
zIndex: Z_INDEX.MODAL_BACKDROP,
},
}}
keepMounted
@@ -39,6 +42,7 @@ const FadeModal = ({
<ModalDialog
size={size}
sx={{
zIndex: Z_INDEX.MODAL_CONTENT,
minWidth: fullWidth ? '100%' : 'auto',
animation: open
? 'modalFadeIn 0.35s forwards'

35
src/constants/zIndex.js Normal file
View File

@@ -0,0 +1,35 @@
// Z-index constants for consistent layering
// Lower values appear behind higher values
export const Z_INDEX = {
// Base layer (0-99)
BASE: 0,
CARD_OVERLAY: 1,
DROPDOWN_ITEM: 2,
TOOLTIP: 3,
// UI Components (100-999)
SAFE_AREA: 100,
CALENDAR: 110,
SMART_INPUT: 110,
AUTOCOMPLETE: 200,
// Navigation (1000-1999)
NAVBAR: 1000,
DRAWER: 999,
// Modals and Overlays (2000-8999)
MODAL_BACKDROP: 2000,
MODAL_CONTENT: 2001,
TOAST: 3000,
// Critical System UI (9000-9999)
LOADING_SCREEN: 9000,
ALERTS: 9500,
NETWORK_BANNER: 9600,
// Maximum (10000+) - Reserved for absolute emergencies
EMERGENCY: 10000,
}
export default Z_INDEX

View File

@@ -1,6 +1,7 @@
import { Alert, Box } from '@mui/joy'
import PropTypes from 'prop-types'
import { createContext, useCallback, useContext, useState } from 'react'
import Z_INDEX from '../constants/zIndex'
const FADE_DURATION = 400 // ms
const ALERT_DURATION = 5000 // ms
@@ -48,7 +49,7 @@ export const AlertsProvider = ({ children }) => {
top: 0,
left: 0,
width: '100%',
zIndex: 10000,
zIndex: Z_INDEX.ALERTS,
overflow: 'hidden',
}}
>

View File

@@ -30,7 +30,7 @@ import {
useCreateChore,
useUpdateChore,
} from '../../queries/ChoreQueries.jsx'
import { useUserProfile } from '../../queries/UserQueries.jsx'
import { useCircleMembers, useUserProfile } from '../../queries/UserQueries.jsx'
import { useNotification } from '../../service/NotificationProvider'
import { getTextColorFromBackgroundColor } from '../../utils/Colors.jsx'
import {
@@ -76,8 +76,6 @@ const ChoreEdit = () => {
const [performers, setPerformers] = useState([])
const [assignStrategy, setAssignStrategy] = useState(ASSIGN_STRATEGIES[2])
const [dueDate, setDueDate] = useState(null)
const [completed, setCompleted] = useState(false)
const [completedDate, setCompletedDate] = useState('')
const [assignedTo, setAssignedTo] = useState(-1)
const [frequencyType, setFrequencyType] = useState('once')
const [frequency, setFrequency] = useState(1)
@@ -110,6 +108,8 @@ const ChoreEdit = () => {
isLoading: isChoreLoading,
refetch: refetchChore,
} = useChore(choreId)
const { data: membersData, isLoading: isMemberDataLoading } =
useCircleMembers()
const { showSuccess, showError } = useNotification()
const [userLabels, setUserLabels] = useState([])
@@ -309,9 +309,13 @@ const ChoreEdit = () => {
setIsNotificable(data.res.notification)
setThingTrigger(data.res.thingChore)
// setDueDate(data.res.dueDate)
// setCompleted(data.res.completed)
// setCompletedDate(data.res.completedDate)
setDueDate(
data.res.nextDueDate
? moment(data.res.nextDueDate).format('YYYY-MM-DDTHH:mm:00')
: null,
)
setCreatedBy(data.res.createdBy)
setUpdatedBy(data.res.updatedBy)
}
}, [choreData, isChoreLoading, searchParams])
@@ -380,7 +384,8 @@ const ChoreEdit = () => {
if (
(isChoreLoading && choreId) ||
isUserLabelsLoading ||
isUserProfileLoading
isUserProfileLoading ||
isMemberDataLoading
) {
return <LoadingComponent />
}
@@ -1009,7 +1014,6 @@ const ChoreEdit = () => {
</Card>
)}
</Box>
{choreId > 0 && (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5, mt: 3 }}>
<Sheet
@@ -1022,7 +1026,7 @@ const ChoreEdit = () => {
<Typography level='body1'>
Created by{' '}
<Chip variant='solid'>
{performers.find(f => f.userId === createdBy)?.displayName}
{membersData.res.find(f => f.userId === createdBy)?.displayName}
</Chip>{' '}
{moment(chore.createdAt).fromNow()}
</Typography>
@@ -1033,7 +1037,10 @@ const ChoreEdit = () => {
<Typography level='body1'>
Updated by{' '}
<Chip variant='solid'>
{performers.find(f => f.userId === updatedBy)?.displayName}
{
membersData.res.find(f => f.userId === updatedBy)
?.displayName
}
</Chip>{' '}
{moment(chore.updatedAt).fromNow()}
</Typography>

View File

@@ -22,6 +22,7 @@ import {
ListItemDecorator,
Typography,
} from '@mui/joy'
import { useState } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import { version } from '../../../package.json'
@@ -81,6 +82,8 @@ const links = [
},
]
import Z_INDEX from '../../constants/zIndex'
const NavBar = () => {
const navigate = useNavigate()
const [drawerOpen, setDrawerOpen] = useState(false)
@@ -110,7 +113,7 @@ const NavBar = () => {
style={{
paddingTop: `calc( env(safe-area-inset-top, 0px))`,
position: 'sticky',
zIndex: 10000,
zIndex: Z_INDEX.NAVBAR,
top: 0,
minHeight: '45px',
backgroundColor: 'var(--joy-palette-background-body)',
@@ -164,7 +167,7 @@ const NavBar = () => {
height:
'calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px))',
overflow: 'auto',
zIndex: 999,
zIndex: Z_INDEX.DRAWER,
},
}}
>

View File

@@ -1,6 +1,7 @@
import { WifiOff } from '@mui/icons-material'
import { Alert, Box } from '@mui/joy'
import { useEffect, useState } from 'react'
import Z_INDEX from '../../constants/zIndex'
import { networkManager } from '../../hooks/NetworkManager'
const NetworkBanner = () => {
@@ -23,7 +24,7 @@ const NetworkBanner = () => {
position: 'fixed',
top: 0,
left: 0,
zIndex: 10001,
zIndex: Z_INDEX.NETWORK_BANNER,
padding: '4px',
pt: `calc( env(safe-area-inset-top, 0px))`,
width: '100%',