Update styling for NavBar and ThingsView components
This commit is contained in:
parent
a57def2f92
commit
568f86acd0
4 changed files with 230 additions and 187 deletions
|
@ -11,12 +11,12 @@ import {
|
|||
PeopleAlt,
|
||||
Person,
|
||||
SwitchAccessShortcut,
|
||||
Timelapse,
|
||||
} from '@mui/icons-material'
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
CardContent,
|
||||
Checkbox,
|
||||
Chip,
|
||||
Container,
|
||||
|
@ -25,8 +25,6 @@ import {
|
|||
Grid,
|
||||
IconButton,
|
||||
Input,
|
||||
ListItem,
|
||||
ListItemContent,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
|
@ -121,62 +119,43 @@ const ChoreView = () => {
|
|||
{
|
||||
size: 6,
|
||||
icon: <PeopleAlt />,
|
||||
text: 'Assigned To',
|
||||
subtext: performers.find(p => p.id === chore.assignedTo)?.displayName,
|
||||
title: 'Assignment',
|
||||
text: `Assigned: ${
|
||||
performers.find(p => p.id === chore.assignedTo)?.displayName || 'N/A'
|
||||
}`,
|
||||
subtext: ` Last: ${
|
||||
chore.lastCompletedDate
|
||||
? performers.find(p => p.id === chore.lastCompletedBy)?.displayName
|
||||
: '--'
|
||||
}`,
|
||||
},
|
||||
{
|
||||
size: 6,
|
||||
icon: <CalendarMonth />,
|
||||
text: 'Due Date',
|
||||
subtext: chore.nextDueDate
|
||||
? moment(chore.nextDueDate).fromNow()
|
||||
: 'N/A',
|
||||
title: 'Schedule',
|
||||
text: `Due: ${
|
||||
chore.nextDueDate ? moment(chore.nextDueDate).fromNow() : 'N/A'
|
||||
}`,
|
||||
subtext: `Last: ${
|
||||
chore.lastCompletedDate
|
||||
? moment(chore.lastCompletedDate).fromNow()
|
||||
: 'N/A'
|
||||
}`,
|
||||
},
|
||||
|
||||
// {
|
||||
// icon: <TextFields />,
|
||||
// text: 'Frequency',
|
||||
// subtext:
|
||||
// chore.frequencyType.charAt(0).toUpperCase() +
|
||||
// chore.frequencyType.slice(1),
|
||||
// },
|
||||
{
|
||||
size: 6,
|
||||
icon: <Checklist />,
|
||||
text: 'Total Completed',
|
||||
subtext: `${chore.totalCompletedCount} times`,
|
||||
},
|
||||
{
|
||||
size: 6,
|
||||
icon: <Timelapse />,
|
||||
text: 'Last Completed',
|
||||
subtext:
|
||||
// chore.lastCompletedDate &&
|
||||
// moment(chore.lastCompletedDate).format('MM/DD/YYYY hh:mm A'),
|
||||
chore.lastCompletedDate && moment(chore.lastCompletedDate).fromNow(),
|
||||
title: 'Statistics',
|
||||
text: `Completed: ${chore.totalCompletedCount || 0} times`,
|
||||
},
|
||||
{
|
||||
size: 6,
|
||||
icon: <Person />,
|
||||
text: 'Last Performer',
|
||||
subtext: chore.lastCompletedDate
|
||||
? `${
|
||||
performers.find(p => p.id === chore.lastCompletedBy)?.displayName
|
||||
}`
|
||||
: '--',
|
||||
title: 'Details',
|
||||
subtext: `Created By: ${
|
||||
performers.find(p => p.id === chore.createdBy)?.displayName || 'N/A'
|
||||
}`,
|
||||
},
|
||||
{
|
||||
size: 6,
|
||||
icon: <Person />,
|
||||
text: 'Created By',
|
||||
subtext: performers.find(p => p.id === chore.createdBy)?.displayName,
|
||||
},
|
||||
// {
|
||||
// size: 12,
|
||||
// icon: <Note />,
|
||||
// text: 'Recent Note',
|
||||
// subtext: chore.notes || '--',
|
||||
// },
|
||||
]
|
||||
setInfoCards(cards)
|
||||
}
|
||||
|
@ -287,38 +266,70 @@ const ChoreView = () => {
|
|||
</Chip>
|
||||
))}
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Sheet
|
||||
<Grid
|
||||
container
|
||||
spacing={1}
|
||||
sx={{
|
||||
mb: 1,
|
||||
borderRadius: 'lg',
|
||||
p: 2,
|
||||
}}
|
||||
variant='outlined'
|
||||
>
|
||||
<Grid container spacing={1}>
|
||||
{infoCards.map((detail, index) => (
|
||||
<Grid item xs={6} key={index}>
|
||||
{/* divider between the list items: */}
|
||||
{infoCards.map((card, index) => (
|
||||
<Grid item xs={6} sm={6} key={index}>
|
||||
<Card
|
||||
variant='soft'
|
||||
sx={{
|
||||
borderRadius: 'md',
|
||||
boxShadow: 1,
|
||||
px: 2,
|
||||
py: 1,
|
||||
minHeight: 90,
|
||||
// change from space-between to start:
|
||||
justifyContent: 'start',
|
||||
}}
|
||||
>
|
||||
<CardContent>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'start',
|
||||
mb: 0.5,
|
||||
}}
|
||||
>
|
||||
{card.icon}
|
||||
|
||||
<ListItem key={index}>
|
||||
<ListItemContent>
|
||||
<Typography level='body-xs' sx={{ fontWeight: 'md' }}>
|
||||
{detail.text}
|
||||
</Typography>
|
||||
<Chip
|
||||
color='primary'
|
||||
size='md'
|
||||
startDecorator={detail.icon}
|
||||
<Typography
|
||||
level='body-md'
|
||||
sx={{
|
||||
ml: 1,
|
||||
fontWeight: '500',
|
||||
color: 'text.primary',
|
||||
}}
|
||||
>
|
||||
{detail.subtext ? detail.subtext : '--'}
|
||||
</Chip>
|
||||
</ListItemContent>
|
||||
</ListItem>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</Sheet>
|
||||
{card.title}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box>
|
||||
<Typography
|
||||
level='body-sm'
|
||||
sx={{ color: 'text.secondary', lineHeight: 1.5 }}
|
||||
>
|
||||
{card.text}
|
||||
</Typography>
|
||||
<Typography
|
||||
level='body-sm'
|
||||
sx={{ color: 'text.secondary', lineHeight: 1.5 }}
|
||||
>
|
||||
{card.subtext}
|
||||
</Typography>
|
||||
</Box>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
|
@ -345,6 +356,7 @@ const ChoreView = () => {
|
|||
p: 1,
|
||||
}}
|
||||
fullWidth
|
||||
variant='plain'
|
||||
>
|
||||
{chorePriority ? chorePriority.icon : <LowPriority />}
|
||||
{chorePriority ? chorePriority.name : 'No Priority'}
|
||||
|
@ -388,7 +400,7 @@ const ChoreView = () => {
|
|||
<Button
|
||||
size='sm'
|
||||
color='neutral'
|
||||
variant='outlined'
|
||||
variant='plain'
|
||||
fullWidth
|
||||
onClick={() => {
|
||||
navigate(`/chores/${choreId}/history`)
|
||||
|
@ -406,7 +418,7 @@ const ChoreView = () => {
|
|||
<Button
|
||||
size='sm'
|
||||
color='neutral'
|
||||
variant='outlined'
|
||||
variant='plain'
|
||||
fullWidth
|
||||
sx={{
|
||||
// top right of the card:
|
||||
|
@ -431,7 +443,7 @@ const ChoreView = () => {
|
|||
</Typography>
|
||||
|
||||
<Sheet
|
||||
variant='outlined'
|
||||
variant='plain'
|
||||
sx={{
|
||||
p: 2,
|
||||
borderRadius: 'lg',
|
||||
|
@ -471,7 +483,7 @@ const ChoreView = () => {
|
|||
<Typography level='title-md' sx={{ mb: 1 }}>
|
||||
Previous note:
|
||||
</Typography>
|
||||
<Sheet variant='outlined' sx={{ p: 2, borderRadius: 'lg' }}>
|
||||
<Sheet variant='plain' sx={{ p: 2, borderRadius: 'lg' }}>
|
||||
<Typography level='body-md' sx={{ mb: 1 }}>
|
||||
{chore.notes || '--'}
|
||||
</Typography>
|
||||
|
@ -479,11 +491,6 @@ const ChoreView = () => {
|
|||
</>
|
||||
)}
|
||||
</Box>
|
||||
{/* <Divider
|
||||
sx={{
|
||||
my: 2,
|
||||
}}
|
||||
/> */}
|
||||
|
||||
<Card
|
||||
sx={{
|
||||
|
@ -492,6 +499,7 @@ const ChoreView = () => {
|
|||
boxShadow: 'sm',
|
||||
mt: 2,
|
||||
}}
|
||||
variant='soft'
|
||||
>
|
||||
<Typography level='body-md' sx={{ mb: 1 }}>
|
||||
Complete the task
|
||||
|
@ -511,16 +519,10 @@ const ChoreView = () => {
|
|||
}
|
||||
}}
|
||||
overlay
|
||||
sx={
|
||||
{
|
||||
// my: 1,
|
||||
}
|
||||
}
|
||||
label={
|
||||
<Typography
|
||||
level='body-sm'
|
||||
sx={{
|
||||
// center vertically
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
|
|
|
@ -13,6 +13,14 @@ import {
|
|||
import moment from 'moment'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Link, useParams } from 'react-router-dom'
|
||||
import {
|
||||
Line,
|
||||
LineChart,
|
||||
ResponsiveContainer,
|
||||
Tooltip,
|
||||
XAxis,
|
||||
YAxis,
|
||||
} from 'recharts'
|
||||
import { GetThingHistory } from '../../utils/Fetcher'
|
||||
|
||||
const ThingsHistory = () => {
|
||||
|
@ -67,7 +75,7 @@ const ThingsHistory = () => {
|
|||
|
||||
return `${timeValue} ${unit}${timeValue !== 1 ? 's' : ''}`
|
||||
}
|
||||
if (errLoading || !thingsHistory) {
|
||||
if (errLoading || !thingsHistory || thingsHistory.length === 0) {
|
||||
return (
|
||||
<Container
|
||||
maxWidth='md'
|
||||
|
@ -107,6 +115,60 @@ const ThingsHistory = () => {
|
|||
<Typography level='h3' mb={1.5}>
|
||||
History:
|
||||
</Typography>
|
||||
{/* check if all the states are number the show it: */}
|
||||
{thingsHistory.every(history => !isNaN(history.state)) &&
|
||||
thingsHistory.length > 1 && (
|
||||
<>
|
||||
<Typography level='h4' gutterBottom>
|
||||
Chart:
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ borderRadius: 'sm', p: 2, boxShadow: 'md', mb: 2 }}>
|
||||
<ResponsiveContainer width='100%' height={200}>
|
||||
<LineChart
|
||||
width={500}
|
||||
height={300}
|
||||
data={thingsHistory.toReversed()}
|
||||
>
|
||||
{/* <CartesianGrid strokeDasharray='3 3' /> */}
|
||||
<XAxis
|
||||
dataKey='updatedAt'
|
||||
hide='true'
|
||||
tick='false'
|
||||
tickLine='false'
|
||||
axisLine='false'
|
||||
tickFormatter={tick =>
|
||||
moment(tick).format('ddd MM/DD/yyyy HH:mm:ss')
|
||||
}
|
||||
/>
|
||||
<YAxis
|
||||
hide='true'
|
||||
dataKey='state'
|
||||
tick='false'
|
||||
tickLine='true'
|
||||
axisLine='false'
|
||||
/>
|
||||
<Tooltip
|
||||
labelFormatter={label =>
|
||||
moment(label).format('ddd MM/DD/yyyy HH:mm:ss')
|
||||
}
|
||||
/>
|
||||
|
||||
<Line
|
||||
type='monotone'
|
||||
dataKey='state'
|
||||
stroke='#8884d8'
|
||||
activeDot={{ r: 8 }}
|
||||
dot={{ r: 4 }}
|
||||
/>
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
<Typography level='h4' gutterBottom>
|
||||
Change log:
|
||||
</Typography>
|
||||
<Box sx={{ borderRadius: 'sm', p: 2, boxShadow: 'md' }}>
|
||||
<List sx={{ p: 0 }}>
|
||||
{thingsHistory.map((history, index) => (
|
||||
|
|
|
@ -10,9 +10,8 @@ import {
|
|||
} from '@mui/icons-material'
|
||||
import {
|
||||
Box,
|
||||
Card,
|
||||
Button,
|
||||
Chip,
|
||||
CircularProgress,
|
||||
Container,
|
||||
Grid,
|
||||
IconButton,
|
||||
|
@ -63,122 +62,102 @@ const ThingCard = ({
|
|||
}
|
||||
|
||||
return (
|
||||
<Card
|
||||
variant='plain'
|
||||
<Box
|
||||
className='rounded-lg border border-zinc-200/80 p-4 shadow-sm'
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
p: 2,
|
||||
boxShadow: 'sm',
|
||||
borderRadius: 20,
|
||||
|
||||
mb: 2,
|
||||
}}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={9}>
|
||||
<Grid container alignItems='center'>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
sm={8}
|
||||
onClick={() => Navigate(`/things/${thing?.id}`)}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 1,
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={() => {
|
||||
Navigate(`/things/${thing?.id}`)
|
||||
}}
|
||||
onClick={() => Navigate(`/things/${thing?.id}`)}
|
||||
>
|
||||
<Typography level='title-lg' component='h2'>
|
||||
{thing?.name}
|
||||
</Typography>
|
||||
<Chip level='body-md' component='p'>
|
||||
<Typography level='title-lg'>{thing?.name}</Typography>
|
||||
<Chip
|
||||
size='sm'
|
||||
sx={{
|
||||
ml: 1,
|
||||
}}
|
||||
>
|
||||
{thing?.type}
|
||||
</Chip>
|
||||
</Box>
|
||||
<Box>
|
||||
<Typography level='body-sm' component='p'>
|
||||
Current state:
|
||||
<Chip level='title-md' component='span' size='sm'>
|
||||
{thing?.state}
|
||||
</Chip>
|
||||
</Typography>
|
||||
</Box>
|
||||
State: <Chip size='md'>{thing?.state}</Chip>
|
||||
</Grid>
|
||||
<Grid item xs={3}>
|
||||
<Box display='flex' justifyContent='flex-end' alignItems='flex-end'>
|
||||
{/* <ButtonGroup> */}
|
||||
<div className='relative grid place-items-center'>
|
||||
<IconButton
|
||||
variant='solid'
|
||||
color='success'
|
||||
onClick={() => {
|
||||
handleRequestChange(thing)
|
||||
}}
|
||||
sx={{
|
||||
borderRadius: '50%',
|
||||
width: 50,
|
||||
minWidth: 50,
|
||||
height: 50,
|
||||
zIndex: 1,
|
||||
}}
|
||||
disabled={isDisabled}
|
||||
>
|
||||
{getThingIcon(thing?.type)}
|
||||
</IconButton>
|
||||
{isDisabled && (
|
||||
<CircularProgress
|
||||
variant='solid'
|
||||
color='success'
|
||||
size='md'
|
||||
sx={{
|
||||
color: 'success.main',
|
||||
position: 'absolute',
|
||||
'--CircularProgress-size': '55px',
|
||||
|
||||
zIndex: 0,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<IconButton
|
||||
// sx={{ width: 15 }}
|
||||
variant='soft'
|
||||
color='success'
|
||||
onClick={() => {
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
sm={4}
|
||||
container
|
||||
justifyContent='flex-end'
|
||||
alignItems='center'
|
||||
>
|
||||
<Button
|
||||
variant='soft'
|
||||
color='success'
|
||||
onClick={() => {
|
||||
if (thing?.type === 'text') {
|
||||
onEditClick(thing)
|
||||
}}
|
||||
sx={{
|
||||
borderRadius: '50%',
|
||||
width: 25,
|
||||
height: 25,
|
||||
position: 'relative',
|
||||
left: -10,
|
||||
}}
|
||||
>
|
||||
<Edit />
|
||||
</IconButton>
|
||||
{/* add delete icon: */}
|
||||
<IconButton
|
||||
// sx={{ width: 15 }}
|
||||
|
||||
color='danger'
|
||||
variant='soft'
|
||||
onClick={() => {
|
||||
onDeleteClick(thing)
|
||||
}}
|
||||
sx={{
|
||||
borderRadius: '50%',
|
||||
width: 25,
|
||||
height: 25,
|
||||
position: 'relative',
|
||||
left: -10,
|
||||
}}
|
||||
>
|
||||
<Delete />
|
||||
</IconButton>
|
||||
</Box>
|
||||
} else {
|
||||
handleRequestChange(thing)
|
||||
}
|
||||
}}
|
||||
disabled={isDisabled}
|
||||
startDecorator={getThingIcon(thing?.type)}
|
||||
>
|
||||
{thing?.type === 'text'
|
||||
? 'Change'
|
||||
: thing?.type === 'number'
|
||||
? 'Increment'
|
||||
: 'Toggle'}
|
||||
</Button>
|
||||
<IconButton
|
||||
color='primary'
|
||||
onClick={() => onEditClick(thing)}
|
||||
sx={{
|
||||
borderRadius: '50%',
|
||||
width: 30,
|
||||
height: 30,
|
||||
ml: 1,
|
||||
transition: 'background-color 0.2s',
|
||||
'&:hover': { backgroundColor: 'action.hover' },
|
||||
}}
|
||||
>
|
||||
<Edit />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
color='danger'
|
||||
onClick={() => onDeleteClick(thing)}
|
||||
sx={{
|
||||
borderRadius: '50%',
|
||||
width: 30,
|
||||
height: 30,
|
||||
ml: 1,
|
||||
}}
|
||||
>
|
||||
<Delete fontSize='small' />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Card>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -105,22 +105,22 @@ const NavBar = () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<nav className='flex gap-2 p-3'>
|
||||
<nav className='flex gap-2 p-2'>
|
||||
<IconButton size='sm' variant='plain' onClick={() => setDrawerOpen(true)}>
|
||||
<MenuRounded />
|
||||
</IconButton>
|
||||
<Box
|
||||
className='flex items-center gap-2'
|
||||
className='flex items-center gap-1'
|
||||
onClick={() => {
|
||||
navigate('/my/chores')
|
||||
}}
|
||||
>
|
||||
<img component='img' src={Logo} width='34' />
|
||||
<img component='img' src={Logo} width='25' />
|
||||
<Typography
|
||||
level='title-lg'
|
||||
sx={{
|
||||
fontWeight: 700,
|
||||
fontSize: 24,
|
||||
fontSize: 20,
|
||||
}}
|
||||
>
|
||||
Done
|
||||
|
|
Loading…
Add table
Reference in a new issue