Skip to content

Commit

Permalink
Feat: Progress Dialog If Actions Done/NotDone (#63)
Browse files Browse the repository at this point in the history
# Background
Renders the following dialog if changes made:

![image](https://github.com/user-attachments/assets/96f4f51c-1ad0-40a8-8bfd-1ef795b9cda5)


## Checklist Before PR Review
- [x] The following has been handled:
  -  `Draft` is set for this PR
  - `Title` is checked
  - `Background` is filled
  - `Assignee` is set
  - `Labels` are set
  - `development` is linked if related issue exists

## Checklist (Right Before PR Review Request)
- [x] The following has been handled:
  - Final Operation Check is done
  - Make this PR as an open PR

## Checklist (Reviewers)
- [x] Check if there are any other missing TODOs that are not yet listed
- [x] Review Code
- [x] Every item on the checklist has been addressed accordingly
- [x] If `development` is associated to this PR, you must check if every
TODOs are handled
  • Loading branch information
mlajkim authored Sep 30, 2024
1 parent 30bebe4 commit 2b04116
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 35 deletions.
2 changes: 2 additions & 0 deletions src/components/organism_appbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import RitualsFrameRefreshButton from '@/components/organism_rituals_frame/index
import AppbarGitHubButtonPart from '../atom_appbar_parts/index.github_icon'
import useWindowSize from 'react-use/lib/useWindowSize'
import RitualsFrameGauge from '../organism_rituals_frame/index.gauge'
import RitualsFrameGaugeDialog from '../organism_rituals_frame/index.gague-dialog'

const PRIVATE_TITLE = `Consistency GPT (Beta)`
const PRIVATE_SHORTER_TITLE = `CGT`
Expand Down Expand Up @@ -75,6 +76,7 @@ const Appbar: FC<Props> = ({ children, nickname }) => {
</Toolbar>
</AppBar>
<Box height="calc(100vh - 48px)">{children}</Box>
<RitualsFrameGaugeDialog />
</Box>
)
}
Expand Down
39 changes: 39 additions & 0 deletions src/components/organism_rituals_frame/index.gague-dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { FC, useEffect, useState } from 'react'
import { useRecoilValue } from 'recoil'
import { actionGroupAchievedPercentSelector } from '@/recoil/action-groups/action-groups.selectors'
import StyledDialog from '@/organisms/StyledDialog'
import { DialogContent, DialogTitle, Stack } from '@mui/material'
import StyledProgressBarMolecule from '@/molecules/StyledProgressBar'

/**
* RitualsFrameGauge shows a simple molecule sized gauge for user's achievement for today
* @param param0
* @returns
*/
const RitualsFrameGaugeDialog: FC = () => {
const [open, setOpen] = useState(false)
const [visual, setVisual] = useState<number>(0)
const percentage = useRecoilValue(actionGroupAchievedPercentSelector)

useEffect(() => {
// if percentage changes, open it for two seconds, and close it
setTimeout(() => setOpen(true), 400)
setTimeout(() => setVisual(percentage), 850)
setTimeout(() => setOpen(false), 2500)
}, [percentage])

if (!open) return null

return (
<StyledDialog>
<DialogTitle>{`Your Achievement Today`}</DialogTitle>
<DialogContent>
<Stack spacing={1}>
<StyledProgressBarMolecule percent={visual} />
</Stack>
</DialogContent>
</StyledDialog>
)
}

export default RitualsFrameGaugeDialog
37 changes: 2 additions & 35 deletions src/components/organism_rituals_frame/index.gauge.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,9 @@
import { FC } from 'react'
import { styled } from '@mui/material/styles'
import LinearProgress, {
linearProgressClasses,
} from '@mui/material/LinearProgress'
import { Box, Typography } from '@mui/material'
import { useRecoilValue } from 'recoil'
import { actionGroupAchievedPercentSelector } from '@/recoil/action-groups/action-groups.selectors'

const PRIVATE_GREEN = `#00e676`
const PRIVATE_GREEN_DARK_MODE = `#00c853`
import StyledProgressBarMolecule from '@/molecules/StyledProgressBar'

interface Props {}
// TODO: Move me somewhere else? (Since BorderLinearProgress is used only within this component, this sits here)
const BorderLinearProgress = styled(LinearProgress)<{ value: number }>(
({ theme, value }) => ({
height: 10,
borderRadius: 5,
[`&.${linearProgressClasses.colorPrimary}`]: {
backgroundColor: theme.palette.grey[200],
...theme.applyStyles(`dark`, {
backgroundColor: theme.palette.grey[800],
}),
},
[`& .${linearProgressClasses.bar}`]: {
borderRadius: 5,
backgroundColor: value === 100 ? PRIVATE_GREEN : `#ffffff`, // White for light theme
...theme.applyStyles(`dark`, {
backgroundColor: value === 100 ? PRIVATE_GREEN_DARK_MODE : `#f5f5f5`, // Lighter white for dark theme
}),
},
}),
)

/**
* RitualsFrameGauge shows a simple molecule sized gauge for user's achievement for today
* @param param0
Expand All @@ -40,12 +12,7 @@ const BorderLinearProgress = styled(LinearProgress)<{ value: number }>(
const RitualsFrameGauge: FC<Props> = () => {
const percentage = useRecoilValue(actionGroupAchievedPercentSelector)

return (
<Box minWidth={200} alignItems={`center`}>
<BorderLinearProgress variant="determinate" value={percentage} />
<Typography>{`${percentage}%`}</Typography>
</Box>
)
return <StyledProgressBarMolecule percent={percentage} />
}

export default RitualsFrameGauge
71 changes: 71 additions & 0 deletions src/molecules/StyledProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { FC, useEffect, useState } from 'react'
import { styled } from '@mui/material/styles'
import LinearProgress, {
linearProgressClasses,
} from '@mui/material/LinearProgress'
import { Box, Typography } from '@mui/material'

const PRIVATE_GREEN = `#00e676`
const PRIVATE_GREEN_DARK_MODE = `#00c853`
const PRIVATE_MIAMI_BLUE = `#54C3EA`

interface Props {
percent: number
}

const BorderLinearProgress = styled(LinearProgress)<{ value: number }>(
({ theme, value }) => ({
height: 10,
borderRadius: 5,
[`&.${linearProgressClasses.colorPrimary}`]: {
backgroundColor: theme.palette.grey[200],
...theme.applyStyles(`dark`, {
backgroundColor: theme.palette.grey[800],
}),
},
[`& .${linearProgressClasses.bar}`]: {
borderRadius: 5,
backgroundColor: value === 100 ? PRIVATE_GREEN : PRIVATE_MIAMI_BLUE,
...theme.applyStyles(`dark`, {
backgroundColor: value === 100 ? PRIVATE_GREEN_DARK_MODE : `#f5f5f5`, // Lighter white for dark theme
}),
},
}),
)

/**
* StyledProgressBarMolecule renders a progress bar with a percentage
*/
const StyledProgressBarMolecule: FC<Props> = ({ percent }) => {
const [animatedPercent, setAnimatedPercent] = useState(percent)

useEffect(() => {
const start = animatedPercent
const duration = 600 // Animation duration in milliseconds
const startTime = performance.now()

const animate = (currentTime: number) => {
const elapsedTime = currentTime - startTime
const progress = Math.min(elapsedTime / duration, 1) // Clamp to 1

// Linear interpolation between start and target percent
const newPercent = Math.round(start + (percent - start) * progress)
setAnimatedPercent(newPercent)

if (progress < 1) {
requestAnimationFrame(animate) // Continue animation if not done
}
}

requestAnimationFrame(animate)
}, [percent, animatedPercent])

return (
<Box minWidth={200} alignItems={`center`}>
<BorderLinearProgress variant="determinate" value={percent} />
<Typography>{`${animatedPercent}%`}</Typography>
</Box>
)
}

export default StyledProgressBarMolecule

0 comments on commit 2b04116

Please sign in to comment.