1+ 'use client'
2+
3+ import { useState , useEffect } from 'react' ;
4+ import { useForm } from 'react-hook-form' ;
5+ import { zodResolver } from '@hookform/resolvers/zod' ;
6+ import * as z from 'zod' ;
7+ import { Button } from '@comp/ui/button' ;
8+ import {
9+ Dialog ,
10+ DialogContent ,
11+ DialogHeader ,
12+ DialogTitle ,
13+ DialogDescription ,
14+ DialogFooter ,
15+ } from '@comp/ui/dialog' ;
16+ import { Input } from '@comp/ui/input' ;
17+ import { Textarea } from '@comp/ui/textarea' ; // Assuming you have a Textarea component
18+ import { Label } from '@comp/ui/label' ;
19+ import { updateControlDetails } from '../../actions' ; // Path to your server actions
20+ import type { ControlDetailsWithRelations } from '../page' ; // Type for control details
21+ import { toast } from 'sonner' ; // For notifications
22+
23+ const formSchema = z . object ( {
24+ name : z . string ( ) . min ( 1 , { message : 'Control name is required.' } ) . max ( 255 ) ,
25+ description : z . string ( ) . max ( 1024 ) . optional ( ) , // Optional, adjust as needed
26+ } ) ;
27+
28+ type EditControlFormValues = z . infer < typeof formSchema > ;
29+
30+ interface EditControlDialogProps {
31+ isOpen : boolean ;
32+ onOpenChange : ( isOpen : boolean ) => void ;
33+ control : Pick < ControlDetailsWithRelations , 'id' | 'name' | 'description' > ;
34+ onControlUpdated : ( ) => void ;
35+ }
36+
37+ export function EditControlDialog ( {
38+ isOpen,
39+ onOpenChange,
40+ control,
41+ onControlUpdated,
42+ } : EditControlDialogProps ) {
43+ const [ isSubmitting , setIsSubmitting ] = useState ( false ) ;
44+
45+ const form = useForm < EditControlFormValues > ( {
46+ resolver : zodResolver ( formSchema ) ,
47+ defaultValues : {
48+ name : control . name || '' ,
49+ description : control . description || '' ,
50+ } ,
51+ } ) ;
52+
53+ useEffect ( ( ) => {
54+ if ( isOpen ) {
55+ form . reset ( {
56+ name : control . name || '' ,
57+ description : control . description || '' ,
58+ } ) ;
59+ }
60+ } , [ isOpen , control , form ] ) ;
61+
62+ const onSubmit = async ( values : EditControlFormValues ) => {
63+ setIsSubmitting ( true ) ;
64+ try {
65+ await updateControlDetails ( control . id , {
66+ name : values . name ,
67+ description : values . description || '' , // Ensure empty string if undefined
68+ } ) ;
69+ toast . success ( 'Control details updated successfully!' ) ;
70+ onControlUpdated ( ) ; // This will typically close dialog and refresh data
71+ onOpenChange ( false ) ; // Explicitly close dialog
72+ } catch ( error ) {
73+ console . error ( "Failed to update control:" , error ) ;
74+ toast . error ( 'Failed to update control. Please try again.' ) ;
75+ } finally {
76+ setIsSubmitting ( false ) ;
77+ }
78+ } ;
79+
80+ return (
81+ < Dialog open = { isOpen } onOpenChange = { onOpenChange } >
82+ < DialogContent className = "sm:max-w-[480px] rounded-sm" >
83+ < DialogHeader >
84+ < DialogTitle > Edit Control Details</ DialogTitle >
85+ < DialogDescription >
86+ Make changes to the control name and description.
87+ </ DialogDescription >
88+ </ DialogHeader >
89+ < form onSubmit = { form . handleSubmit ( onSubmit ) } className = "space-y-4 py-2" >
90+ < div className = "space-y-2" >
91+ < Label htmlFor = "name" > Control Name</ Label >
92+ < Input
93+ id = "name"
94+ { ...form . register ( 'name' ) }
95+ placeholder = "Enter control name"
96+ className = "rounded-sm"
97+ />
98+ { form . formState . errors . name && (
99+ < p className = "text-xs text-red-500" > { form . formState . errors . name . message } </ p >
100+ ) }
101+ </ div >
102+ < div className = "space-y-2" >
103+ < Label htmlFor = "description" > Description (Optional)</ Label >
104+ < Textarea
105+ id = "description"
106+ { ...form . register ( 'description' ) }
107+ placeholder = "Enter control description"
108+ rows = { 4 }
109+ className = "rounded-sm"
110+ />
111+ { form . formState . errors . description && (
112+ < p className = "text-xs text-red-500" > { form . formState . errors . description . message } </ p >
113+ ) }
114+ </ div >
115+ < DialogFooter >
116+ < Button type = "button" variant = "outline" onClick = { ( ) => onOpenChange ( false ) } disabled = { isSubmitting } className = "rounded-sm" >
117+ Cancel
118+ </ Button >
119+ < Button type = "submit" disabled = { isSubmitting } className = "rounded-sm" >
120+ { isSubmitting ? 'Saving...' : 'Save Changes' }
121+ </ Button >
122+ </ DialogFooter >
123+ </ form >
124+ </ DialogContent >
125+ </ Dialog >
126+ ) ;
127+ }
0 commit comments