1
1
'use client' ;
2
2
3
+ import { InputTags } from "@/components/InputTags" ;
4
+ import { Button } from "@/components/ui/button" ;
3
5
import { Card , CardContent , CardDescription , CardHeader , CardTitle } from "@/components/ui/card" ;
6
+ import { Checkbox } from "@/components/ui/checkbox" ;
7
+ import { Input } from "@/components/ui/input" ;
8
+ import { Label } from "@/components/ui/label" ;
9
+ import { updateProjectSettingsAction } from "@/data/user/projects" ;
10
+ import { useSAToastMutation } from "@/hooks/useSAToastMutation" ;
11
+ import { Tables } from "@/lib/database.types" ;
4
12
import { motion } from "framer-motion" ;
13
+ import { useState } from "react" ;
14
+ import { Controller , useForm } from "react-hook-form" ;
15
+
16
+ type ProjectSettingsProps = {
17
+ project : Tables < 'projects' > ;
18
+ repositoryName : string | null ;
19
+ } ;
20
+
21
+ type ProjectSettingsFormData = {
22
+ terraformWorkingDir : string ;
23
+ labels : string [ ] ;
24
+ managedState : boolean ;
25
+ } ;
26
+
27
+ export default function ProjectSettings ( { project, repositoryName } : ProjectSettingsProps ) {
28
+ const [ isSubmitting , setIsSubmitting ] = useState ( false ) ;
29
+
30
+ const { control, handleSubmit, formState : { isDirty } } = useForm < ProjectSettingsFormData > ( {
31
+ defaultValues : {
32
+ terraformWorkingDir : project . terraform_working_dir || '' ,
33
+ labels : project . labels || [ ] ,
34
+ managedState : project . is_managing_state || false ,
35
+ } ,
36
+ } ) ;
37
+
38
+ const updateProjectSettingsMutation = useSAToastMutation (
39
+ async ( data : ProjectSettingsFormData ) => {
40
+ const result = await updateProjectSettingsAction ( {
41
+ projectId : project . id ,
42
+ terraformWorkingDir : data . terraformWorkingDir ,
43
+ labels : data . labels ,
44
+ managedState : data . managedState ,
45
+ } ) ;
46
+ return result ;
47
+ } ,
48
+ {
49
+ loadingMessage : "Updating project settings..." ,
50
+ successMessage : "Project settings updated successfully!" ,
51
+ errorMessage : "Failed to update project settings" ,
52
+ }
53
+ ) ;
54
+
55
+ const onSubmit = async ( data : ProjectSettingsFormData ) => {
56
+ setIsSubmitting ( true ) ;
57
+ try {
58
+ await updateProjectSettingsMutation . mutateAsync ( data ) ;
59
+ } catch ( error ) {
60
+ console . error ( "Error updating project settings:" , error ) ;
61
+ } finally {
62
+ setIsSubmitting ( false ) ;
63
+ }
64
+ } ;
5
65
6
- export default function ProjectSettings ( ) {
7
66
return (
8
67
< motion . div
9
68
initial = { { opacity : 0 , y : 10 } }
@@ -12,24 +71,103 @@ export default function ProjectSettings() {
12
71
transition = { { duration : 0.1 } }
13
72
>
14
73
< Card className = "w-full" >
15
- < motion . div
16
- initial = { { opacity : 0 , y : - 5 } }
17
- animate = { { opacity : 1 , y : 0 } }
18
- transition = { { duration : 0.15 , delay : 0.1 } }
19
- >
20
- < CardHeader >
21
- < CardTitle > Project Settings</ CardTitle >
22
- < CardDescription > Manage settings for your project</ CardDescription >
23
- </ CardHeader >
24
- </ motion . div >
74
+ < CardHeader >
75
+ < CardTitle > Project Settings</ CardTitle >
76
+ < CardDescription > Manage settings for your project</ CardDescription >
77
+ </ CardHeader >
25
78
< CardContent >
26
- < motion . div
27
- initial = { { opacity : 0 } }
28
- animate = { { opacity : 1 } }
29
- transition = { { duration : 0.15 , delay : 0.2 } }
30
- >
31
- { /* Add your project settings management component here */ }
32
- </ motion . div >
79
+ < form onSubmit = { handleSubmit ( onSubmit ) } className = "space-y-6" >
80
+ < div className = "grid grid-cols-2 gap-6" >
81
+ < motion . div
82
+ initial = { { opacity : 0 } }
83
+ animate = { { opacity : 1 } }
84
+ transition = { { duration : 0.15 , delay : 0.1 } }
85
+ >
86
+ < Label htmlFor = "name" > Project Name</ Label >
87
+ < Input id = "name" value = { project . name } disabled />
88
+ </ motion . div >
89
+
90
+ < motion . div
91
+ initial = { { opacity : 0 } }
92
+ animate = { { opacity : 1 } }
93
+ transition = { { duration : 0.15 , delay : 0.2 } }
94
+ >
95
+ < Label htmlFor = "repo" > Repository</ Label >
96
+ < Input id = "repo" value = { repositoryName || 'N/A' } disabled />
97
+ </ motion . div >
98
+ </ div >
99
+
100
+ < motion . div
101
+ initial = { { opacity : 0 } }
102
+ animate = { { opacity : 1 } }
103
+ transition = { { duration : 0.15 , delay : 0.3 } }
104
+ className = "flex items-center space-x-2"
105
+ >
106
+ < Controller
107
+ name = "managedState"
108
+ control = { control }
109
+ render = { ( { field } ) => (
110
+ < Checkbox
111
+ id = "managedState"
112
+ checked = { field . value }
113
+ onCheckedChange = { field . onChange }
114
+ disabled
115
+ />
116
+ ) }
117
+ />
118
+ < Label htmlFor = "managedState" > Managed State</ Label >
119
+ </ motion . div >
120
+
121
+ < motion . div
122
+ initial = { { opacity : 0 } }
123
+ animate = { { opacity : 1 } }
124
+ transition = { { duration : 0.15 , delay : 0.4 } }
125
+ >
126
+ < Label htmlFor = "terraformWorkingDir" > Terraform Working Directory</ Label >
127
+ < Controller
128
+ name = "terraformWorkingDir"
129
+ control = { control }
130
+ render = { ( { field } ) => (
131
+ < Input id = "terraformWorkingDir" { ...field } />
132
+ ) }
133
+ />
134
+ </ motion . div >
135
+
136
+ < motion . div
137
+ initial = { { opacity : 0 } }
138
+ animate = { { opacity : 1 } }
139
+ transition = { { duration : 0.15 , delay : 0.5 } }
140
+ >
141
+ < Label htmlFor = "labels" > Labels</ Label >
142
+ < Controller
143
+ name = "labels"
144
+ control = { control }
145
+ render = { ( { field } ) => (
146
+ < InputTags
147
+ id = "labels"
148
+ value = { field . value }
149
+ onChange = { field . onChange }
150
+ placeholder = "Add labels"
151
+ className = "mt-1"
152
+ />
153
+ ) }
154
+ />
155
+ </ motion . div >
156
+
157
+ < motion . div
158
+ initial = { { opacity : 0 } }
159
+ animate = { { opacity : 1 } }
160
+ transition = { { duration : 0.15 , delay : 0.6 } }
161
+ className = "flex justify-end"
162
+ >
163
+ < Button
164
+ type = "submit"
165
+ disabled = { ! isDirty || isSubmitting || updateProjectSettingsMutation . isLoading }
166
+ >
167
+ { isSubmitting || updateProjectSettingsMutation . isLoading ? "Saving..." : "Save Changes" }
168
+ </ Button >
169
+ </ motion . div >
170
+ </ form >
33
171
</ CardContent >
34
172
</ Card >
35
173
</ motion . div >
0 commit comments