"use client" ;
import { useState } from "react" ;
import { PiggyBank, Check } from "lucide-react" ;
import { Button } from "@/components/ui/button" ;
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog" ;
import { Progress } from "@/components/ui/progress" ;
import { cn } from "@/lib/utils" ;
const goal = {
name: "Vacation Fund" ,
target: 2000 ,
current: 1340 ,
};
const quickAmounts = [ 25 , 50 , 100 , 250 ];
export const title = "React Dialog Block Savings Goal" ;
export default function DialogSavingsGoal () {
const [ open , setOpen ] = useState ( false );
const [ selected , setSelected ] = useState < number | null >( null );
const [ deposited , setDeposited ] = useState ( false );
const progress = Math. round ((goal.current / goal.target) * 100 );
const remaining = goal.target - goal.current;
const handleDeposit = () => {
if ( ! selected) return ;
setDeposited ( true );
};
const handleClose = () => {
setOpen ( false );
setTimeout (() => {
setSelected ( null );
setDeposited ( false );
}, 200 );
};
return (
< Dialog open = {open} onOpenChange = {setOpen}>
< div className = "flex min-h-[350px] items-center justify-center" >
< DialogTrigger asChild >
< Button variant = "outline" >
< PiggyBank className = "mr-2 h-4 w-4" />
Savings Goal
</ Button >
</ DialogTrigger >
</ div >
< DialogContent style = {{ maxWidth: "384px" }}>
{deposited ? (
< div className = "flex flex-col items-center justify-center py-6 text-center" >
< Check className = "h-8 w-8 text-primary" />
< h3 className = "mt-4 text-lg font-medium" >Deposit Added</ h3 >
< p className = "mt-1 text-sm text-muted-foreground" >
${selected} added to {goal.name}
</ p >
< Button onClick = {handleClose} className = "mt-6" >
Done
</ Button >
</ div >
) : (
<>
< DialogHeader >
< DialogTitle >{goal.name}</ DialogTitle >
< DialogDescription >
${remaining. toLocaleString ()} left to reach your goal
</ DialogDescription >
</ DialogHeader >
< div className = "py-4 space-y-4" >
{ /* Progress */ }
< div className = "space-y-2" >
< div className = "flex justify-between text-sm" >
< span className = "font-medium" >${goal.current. toLocaleString ()}</ span >
< span className = "text-muted-foreground" >
${goal.target. toLocaleString ()}
</ span >
</ div >
< Progress value = {progress} className = "h-2" />
< p className = "text-xs text-muted-foreground text-center" >
{progress}% complete
</ p >
</ div >
{ /* Quick deposit */ }
< div className = "space-y-2" >
< p className = "text-sm font-medium" >Quick deposit</ p >
< div className = "grid grid-cols-4 gap-2" >
{quickAmounts. map (( amount ) => (
< button
key = {amount}
onClick = {() => setSelected (amount)}
className = { cn (
"py-2 rounded-md border text-sm font-medium transition-colors" ,
selected === amount
? "border-primary bg-primary/5"
: "hover:border-muted-foreground/50"
)}
>
${amount}
</ button >
))}
</ div >
</ div >
</ div >
< DialogFooter >
< Button variant = "outline" onClick = {handleClose}>
Cancel
</ Button >
< Button onClick = {handleDeposit} disabled = { ! selected}>
Add ${selected || 0 }
</ Button >
</ DialogFooter >
</>
)}
</ DialogContent >
</ Dialog >
);
}