style: update Calendar styles for improved UI consistency; enhance CalendarView layout and chore display logic
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user