DiskCountdownRadial.tsx71 lines · main
1import { useParams } from 'common'
2import { AnimatePresence, motion } from 'framer-motion'
3import { useEffect, useState } from 'react'
4import { Card, CardContent } from 'ui'
5
6import FormMessage from './FormMessage'
7import CountdownTimerRadial from '@/components/ui/CountdownTimer/CountdownTimerRadial'
8import CountdownTimerSpan from '@/components/ui/CountdownTimer/CountdownTimerSpan'
9import { useRemainingDurationForDiskAttributeUpdate } from '@/data/config/disk-attributes-query'
10import { COOLDOWN_DURATION } from '@/data/config/disk-attributes-update-mutation'
11
12export function DiskCountdownRadial() {
13 const { ref } = useParams()
14 const [remainingTime, setRemainingTime] = useState(0)
15
16 const {
17 remainingDuration: initialRemainingTime,
18 error,
19 isSuccess,
20 } = useRemainingDurationForDiskAttributeUpdate({
21 projectRef: ref,
22 })
23
24 const progressPercentage = (remainingTime / COOLDOWN_DURATION) * 100
25
26 useEffect(() => {
27 if (initialRemainingTime > 0) setRemainingTime(initialRemainingTime)
28 }, [initialRemainingTime])
29
30 useEffect(() => {
31 if (remainingTime <= 0) return
32
33 const timer = setInterval(() => {
34 setRemainingTime(Math.max(0, remainingTime - 1))
35 }, 1000)
36
37 return () => clearInterval(timer)
38 }, [remainingTime])
39
40 return (
41 <AnimatePresence>
42 {remainingTime > 0 && isSuccess && (
43 <motion.div
44 initial={{ opacity: 0, height: 0 }}
45 animate={{ opacity: 1, height: 'auto' }}
46 exit={{ opacity: 0, height: 0 }}
47 transition={{ duration: 0.2 }}
48 >
49 <Card className="px-2 rounded-sm bg-surface-100">
50 <CardContent className="py-3 flex gap-3 px-3 items-start">
51 <CountdownTimerRadial progress={progressPercentage} />
52 <div className="flex flex-col gap-2">
53 <div>
54 <p className="text-foreground text-sm p-0">
55 4-hour cooldown period is in progress
56 </p>
57 <p className="text-foreground-lighter text-sm p-0">
58 You can't modify your disk configuration again until the 4-hour cool down period
59 ends.
60 </p>
61 </div>
62 <CountdownTimerSpan seconds={remainingTime} />
63 </div>
64 </CardContent>
65 </Card>
66 </motion.div>
67 )}
68 {error && <FormMessage message={error.message} type="error" />}
69 </AnimatePresence>
70 )
71}