style: update Calendar styles for improved UI consistency; enhance CalendarView layout and chore display logic

This commit is contained in:
Mo Tarbin
2025-05-29 01:02:19 -04:00
parent 97abf2f230
commit 2a85b621f5
2 changed files with 207 additions and 67 deletions

View File

@@ -39,49 +39,49 @@
}
.react-calendar__tile:enabled:hover {
background-color: rgba(8, 114, 221, 0.08);
color: #0872dd;
background-color: var(--joy-palette-primary-softBg);
color: var(--joy-palette-primary-solidColor);
}
/* Active/Selected date */
.react-calendar__tile--active {
background-color: #0872dd !important;
color: white !important;
background-color: var(--joy-palette-primary-solidBg) !important;
color: var(--joy-palette-primary-solidColor) !important;
border: none !important;
box-shadow: 0 2px 4px rgba(8, 114, 221, 0.2);
box-shadow: 0 2px 4px var(--joy-palette-primary-shadowRing);
}
.react-calendar__tile--active:hover {
background-color: #0766c7 !important;
background-color: var(--joy-palette-primary-solidHoverBg) !important;
}
/* Today's date */
.react-calendar__tile--now {
background-color: transparent !important;
border: 1.5px solid #0872dd !important;
color: #0872dd !important;
border: 1.5px solid var(--joy-palette-primary-solidBg) !important;
color: var(--joy-palette-primary-solidBg) !important;
font-weight: 500;
}
.react-calendar__tile--now:enabled:hover {
background-color: rgba(8, 114, 221, 0.08) !important;
background-color: var(--joy-palette-primary-softBg) !important;
}
/* Disabled dates */
.react-calendar__tile:disabled {
color: #cbd5e1;
color: var(--joy-palette-text-tertiary);
cursor: not-allowed;
background: transparent;
}
/* Weekend dates */
.react-calendar__month-view__days__day--weekend {
color: #64748b;
color: var(--joy-palette-text-secondary);
}
/* Neighboring month dates */
.react-calendar__month-view__days__day--neighboringMonth {
color: #94a3b8;
color: var(--joy-palette-text-tertiary);
}
.dot-container {
@@ -128,3 +128,73 @@
opacity 0.2s ease,
visibility 0.2s ease;
}
/* Year view month tiles - override circular styling */
.react-calendar__year-view__months__month {
border-radius: 8px !important; /* Override the 50% circular radius */
padding: 12px 8px !important;
min-width: 60px !important;
max-height: 50px !important;
font-size: 0.875rem;
font-weight: 500;
}
.react-calendar__year-view__months__month:enabled:hover {
background-color: var(--joy-palette-primary-softBg) !important;
color: var(--joy-palette-primary-solidColor) !important;
}
/* Decade view year tiles - similar fix */
.react-calendar__decade-view__years__year {
border-radius: 8px !important;
padding: 12px 8px !important;
min-width: 60px !important;
max-height: 50px !important;
font-size: 0.875rem;
font-weight: 500;
}
.react-calendar__decade-view__years__year:enabled:hover {
background-color: var(--joy-palette-primary-softBg) !important;
color: var(--joy-palette-primary-solidColor) !important;
}
/* Century view decade tiles */
.react-calendar__century-view__decades__decade {
border-radius: 8px !important;
padding: 12px 8px !important;
min-width: 60px !important;
max-height: 50px !important;
font-size: 0.875rem;
font-weight: 500;
}
.react-calendar__century-view__decades__decade:enabled:hover {
background-color: var(--joy-palette-primary-softBg) !important;
color: var(--joy-palette-primary-solidColor) !important;
}
/* Navigation buttons (month/year selectors and arrows) */
.react-calendar__navigation button {
border-radius: 8px !important; /* Override circular border-radius */
padding: 6px 12px !important;
min-width: auto !important;
max-height: none !important;
font-weight: 500;
background-color: transparent;
border: 1px solid transparent;
transition: all 0.2s ease-in-out;
color: var(--joy-palette-text-primary);
}
.react-calendar__navigation button:enabled:hover {
background-color: var(--joy-palette-primary-softBg) !important;
color: var(--joy-palette-primary-solidColor) !important;
border-color: var(--joy-palette-primary-outlinedBorder);
}
.react-calendar__navigation button:enabled:focus {
background-color: var(--joy-palette-primary-softActiveBg) !important;
outline: none;
box-shadow: 0 0 0 2px var(--joy-palette-primary-outlinedBorder);
}

View File

@@ -1,12 +1,12 @@
import { CalendarMonth } from '@mui/icons-material'
import { Box, Card, CardContent, Chip, Grid, Typography } from '@mui/joy'
import { Box, Chip, Grid, Typography } from '@mui/joy'
import moment from 'moment'
import React, { useState } from 'react'
import Calendar from 'react-calendar'
import 'react-calendar/dist/Calendar.css'
import { useNavigate } from 'react-router-dom'
import { UserContext } from '../../contexts/UserContext'
import { getTextColorFromBackgroundColor, TASK_COLOR } from '../../utils/Colors'
import { TASK_COLOR } from '../../utils/Colors'
import './Calendar.css'
const getAssigneeColor = (assignee, userProfile) => {
@@ -93,7 +93,7 @@ const CalendarView = ({ chores }) => {
mb: 2,
}}
>
<CalendarMonth color='primary' />
<CalendarMonth />
<Typography level='title-md'>Calendar Overview</Typography>
</Box>
@@ -141,66 +141,136 @@ const CalendarView = ({ chores }) => {
)}
{selectedDate && (
<Box
variant='outlined'
sx={{
// p: 2,
// borderRadius: 20,
// if exceed the height, scroll:
mt: 1,
maxHeight: '160px',
overflowY: 'auto',
// minimum height to fit the content:
height: '50vh',
mt: 2,
width: '100%',
display: 'flex',
flexDirection: 'column',
gap: 2,
}}
>
{chores
.filter(chore => {
const choreDate = new Date(chore.nextDueDate).toLocaleDateString()
const selectedLocalDate = selectedDate.toLocaleDateString()
return choreDate === selectedLocalDate
})
.map((chore, idx) => (
<Card
key={idx}
variant='outlined'
onClick={() => {
Navigate('/chores/' + chore.id)
}}
sx={{
mb: 0.4,
py: 1,
px: 1,
cursor: 'pointer',
}}
>
<CardContent>
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
width: '100%',
}}
>
<Typography level='title-md'>
{moment(selectedDate).format('MMMM D, YYYY')}
</Typography>
<Chip variant='soft' color='primary' size='md'>
{(() => {
const count = chores.filter(chore => {
const choreDate = new Date(
chore.nextDueDate,
).toLocaleDateString()
const selectedLocalDate = selectedDate.toLocaleDateString()
return choreDate === selectedLocalDate
}).length
return `${count} Tasks`
})()}
</Chip>
</Box>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
gap: 1,
// maxHeight: 'calc(100vh - 500px)',
overflowY: 'auto',
maxHeight: '170px',
p: 1,
}}
>
{chores
.filter(chore => {
const choreDate = new Date(
chore.nextDueDate,
).toLocaleDateString()
const selectedLocalDate = selectedDate.toLocaleDateString()
return choreDate === selectedLocalDate
})
.sort((a, b) => moment(a.nextDueDate).diff(moment(b.nextDueDate)))
.map((chore, idx) => (
<Box
key={idx}
onClick={() => {
Navigate('/chores/' + chore.id)
}}
sx={{
display: 'flex',
flexDirection: 'column',
gap: 0.25,
cursor: 'pointer',
position: 'relative',
pl: '16px',
py: 0.75,
transition: 'all 0.2s ease-in-out',
borderRadius: 'sm',
'&:hover': {
// transform: 'translateX(4px)',
bgcolor: 'background.level1',
},
'&::before': {
content: '""',
position: 'absolute',
left: 0,
top: 0,
bottom: 0,
width: '3px',
backgroundColor: getAssigneeColor(
chore.assignedTo,
userProfile,
),
borderRadius: '2px',
},
}}
>
<Typography
key={chore.id}
className='truncate'
maxWidth='100%'
level='body-sm'
sx={{
flex: 1,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
color: 'text.primary',
}}
>
<Chip
variant='plain'
size='sm'
sx={{
backgroundColor: getAssigneeColor(
chore.assignedTo,
userProfile,
),
mr: 0.5,
color: getTextColorFromBackgroundColor(
getAssigneeColor(chore.assignedTo, userProfile),
),
}}
>
{moment(chore.nextDueDate).format('hh:mm A')}
</Chip>
{chore.name}
</Typography>
</CardContent>
</Card>
))}
<Box
sx={{
display: 'flex',
alignItems: 'center',
gap: 1,
}}
>
<Typography
level='body-xs'
sx={{
color: 'neutral.500',
}}
>
{moment(chore.nextDueDate).format('h:mm A')}
</Typography>
<Typography
level='body-xs'
sx={{
color: getAssigneeColor(chore.assignedTo, userProfile),
}}
>
{chore.assignedTo === userProfile.id
? 'Assigned to me'
: 'Assigned to other'}
</Typography>
</Box>
</Box>
))}
</Box>
</Box>
)}
</div>