Skip to content

Commit ad76a72

Browse files
authored
add dashboard clock (#4225)
1 parent ff04662 commit ad76a72

File tree

6 files changed

+80
-6
lines changed

6 files changed

+80
-6
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"editor.tabSize": 2,
33
"editor.codeActionsOnSave": {
4-
"source.organizeImports": true
4+
"source.organizeImports": "explicit"
55
},
66
"scss.lint.unknownAtRules": "ignore",
77
"files.exclude": {

src/components/v2v3/V2V3Project/ProjectDashboard/ProjectDashboard.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { NftRewardsCard } from './components/NftRewardsCard/NftRewardsCard'
1111
import { PayProjectCard } from './components/PayProjectCard/PayProjectCard'
1212
import { ProjectCartProvider } from './components/ProjectCartProvider/ProjectCartProvider'
1313
import { ProjectHeader } from './components/ProjectHeader/ProjectHeader'
14+
import { ProjectHeaderCountdown } from './components/ProjectHeaderCountdown'
1415
import { ProjectTabs } from './components/ProjectTabs/ProjectTabs'
1516
import { ProjectUpdatesProvider } from './components/ProjectUpdatesProvider/ProjectUpdatesProvider'
1617
import { SuccessPayView } from './components/SuccessPayView/SuccessPayView'
@@ -33,7 +34,10 @@ export const ProjectDashboard = () => {
3334
<SuccessPayView />
3435
) : (
3536
<>
36-
<CoverPhoto />
37+
<div className="relative w-full">
38+
<CoverPhoto />
39+
<ProjectHeaderCountdown />
40+
</div>
3741
<div className="flex w-full justify-center md:px-6">
3842
<div className="flex w-full max-w-6xl flex-col">
3943
<ProjectHeader className="mt-12 px-4 md:mt-4 md:px-0" />

src/components/v2v3/V2V3Project/ProjectDashboard/components/CoverPhoto/CoverPhoto.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export const CoverPhoto = () => {
3535
alt={coverImageAltText}
3636
/>
3737
{applyDarkerCoverPhoto && (
38-
<div className="absolute h-70 w-full bg-black opacity-30" />
38+
<div className="absolute h-70 w-full bg-black opacity-30 drop-shadow" />
3939
)}
4040
</>
4141
)}

src/components/v2v3/V2V3Project/ProjectDashboard/components/FundingCycleCountdown/FundingCycleCountdownProvider.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ import { createContext } from 'react'
44

55
type FundingCycleCountdownContextType = {
66
timeRemainingText: string
7+
endEpochSeconds: number
8+
secondsRemaining: number
79
}
810

911
export const FundingCycleCountdownContext =
1012
createContext<FundingCycleCountdownContextType>({
1113
timeRemainingText: '0d 0h 0m 0s',
14+
endEpochSeconds: 0,
15+
secondsRemaining: 0,
1216
})
1317

1418
export const FundingCycleCountdownProvider = ({
@@ -20,13 +24,16 @@ export const FundingCycleCountdownProvider = ({
2024

2125
const endEpochSeconds = fundingCycle
2226
? fundingCycle.start.add(fundingCycle.duration).toNumber()
23-
: undefined
27+
: 0
2428

25-
const remainingTimeText = useCountdownClock(endEpochSeconds)
29+
const { remainingTimeText, secondsRemaining } =
30+
useCountdownClock(endEpochSeconds)
2631
return (
2732
<FundingCycleCountdownContext.Provider
2833
value={{
2934
timeRemainingText: remainingTimeText,
35+
endEpochSeconds,
36+
secondsRemaining,
3037
}}
3138
>
3239
{children}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { ReactNode, useMemo } from 'react'
2+
import { twMerge } from 'tailwind-merge'
3+
import { useFundingCycleCountdown } from '../hooks/useFundingCycleCountdown'
4+
import { useProjectMetadata } from '../hooks/useProjectMetadata'
5+
6+
const RS_PROJECT_ID = 618
7+
8+
export type ProjectHeaderCountdownProps = {
9+
className?: string
10+
}
11+
12+
export const ProjectHeaderCountdown: React.FC<ProjectHeaderCountdownProps> = ({
13+
className,
14+
}) => {
15+
const { projectId } = useProjectMetadata()
16+
const { secondsRemaining } = useFundingCycleCountdown()
17+
18+
const { days, hours, minutes, seconds } = useMemo(() => {
19+
const days = Math.floor(secondsRemaining / (3600 * 24))
20+
const hours = Math.floor((secondsRemaining % (3600 * 24)) / 3600)
21+
const minutes = Math.floor((secondsRemaining % 3600) / 60)
22+
const seconds = Math.floor(secondsRemaining % 60)
23+
return { days, hours, minutes, seconds }
24+
}, [secondsRemaining])
25+
26+
if (projectId !== RS_PROJECT_ID) return null
27+
28+
if (secondsRemaining === 0) return null
29+
30+
return (
31+
<div
32+
className={twMerge(
33+
'absolute bottom-5 left-1/2 mx-auto flex w-full max-w-6xl -translate-x-1/2 items-center justify-end pr-4 md:pr-5 xl:pr-0',
34+
className,
35+
)}
36+
>
37+
<div className="mr-3 text-lg text-white">Closing in</div>
38+
<div className="flex gap-3">
39+
<CountdownCard label="DAYS" unit={days} />
40+
<CountdownCard label="HRS" unit={hours} />
41+
<CountdownCard label="MINS" unit={minutes} />
42+
<CountdownCard label="SECS" unit={seconds} />
43+
</div>
44+
</div>
45+
)
46+
}
47+
48+
export const CountdownCard = ({
49+
label,
50+
unit,
51+
}: {
52+
label: ReactNode
53+
unit: number
54+
}) => (
55+
<div className="flex w-11 flex-1 flex-col items-center rounded-lg border border-smoke-75 bg-smoke-50 py-1 px-1.5 text-black drop-shadow dark:border-slate-400 dark:bg-slate-700 dark:text-white">
56+
<div className="text-xl">{unit}</div>
57+
<div className="text-xs font-medium text-grey-500 dark:text-slate-200">
58+
{label}
59+
</div>
60+
</div>
61+
)

src/components/v2v3/V2V3Project/ProjectDashboard/hooks/useCountdownClock.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@ import { timeSecondsToDateString } from '../utils/timeSecondsToDateString'
66
*/
77
export const useCountdownClock = (endSeconds: number | undefined) => {
88
const [remainingTime, setRemainingTime] = useState<string>('')
9+
const [secondsRemaining, setSecondsRemaining] = useState<number>(0)
910
useEffect(() => {
1011
if (!endSeconds) return
1112
const fn = () => {
1213
const now = Date.now() / 1000
1314
const remaining = endSeconds - now > 0 ? endSeconds - now : 0
15+
setSecondsRemaining(remaining)
1416
setRemainingTime(timeSecondsToDateString(remaining))
1517
}
1618
fn()
1719
const timer = setInterval(fn, 1000)
1820
return () => clearInterval(timer)
1921
}, [endSeconds])
20-
return remainingTime
22+
return { remainingTimeText: remainingTime, secondsRemaining }
2123
}

0 commit comments

Comments
 (0)