1
- "use client"
2
-
3
1
import { createPasswordItem } from "@/app/actions" ;
4
2
import { Button } from "@/components/ui/button" ;
5
3
import { Dialog , DialogContent , DialogFooter , DialogHeader , DialogTitle } from "@/components/ui/dialog" ;
6
4
import { Input } from "@/components/ui/input" ;
7
5
import { encrypt } from "@/utils/encryption" ;
8
6
import { useUser } from "@clerk/nextjs" ;
9
7
import { Loader2 } from "lucide-react" ;
10
- import { useState } from "react" ;
8
+ import { ChangeEvent , useState } from "react" ;
11
9
import toast from "react-hot-toast" ;
12
10
import { z } from "zod" ;
13
11
12
+ const initialPasswordItemState = {
13
+ name : "" ,
14
+ username : "" ,
15
+ website : "" ,
16
+ password : "" ,
17
+ }
18
+
14
19
export const CreatePasswordDialog = ( {
15
20
open,
16
- onClose,
21
+ onClose,
17
22
} : {
18
23
open : boolean ;
19
- onClose : ( ) => void ;
24
+ onClose : ( ) => void
20
25
} ) => {
21
- const [ name , setName ] = useState ( "" ) ;
22
- const [ username , setUsername ] = useState ( "" ) ;
23
- const [ website , setWebsite ] = useState ( "" ) ;
24
- const [ password , setPassword ] = useState ( "" ) ;
26
+
27
+ const [ passwordItem , setPasswordItem ] = useState ( initialPasswordItemState )
28
+
25
29
const [ loading , setLoading ] = useState ( false ) ;
26
30
27
31
const { user : clerkuser } = useUser ( ) ;
@@ -47,12 +51,7 @@ export const CreatePasswordDialog = ({
47
51
48
52
const handleSave = async ( ) => {
49
53
setLoading ( true ) ;
50
- const validationResult = passwordSchema . safeParse ( {
51
- name,
52
- username,
53
- website,
54
- password,
55
- } ) ;
54
+ const validationResult = passwordSchema . safeParse ( passwordItem ) ;
56
55
57
56
if ( ! validationResult . success ) {
58
57
const errorMessage =
@@ -64,11 +63,12 @@ export const CreatePasswordDialog = ({
64
63
65
64
try {
66
65
await createPasswordItem (
67
- encrypt ( username , clerkuser ) ,
68
- encrypt ( website , clerkuser ) ,
69
- encrypt ( password , clerkuser )
66
+ encrypt ( passwordItem . username , clerkuser ) ,
67
+ encrypt ( passwordItem . website , clerkuser ) ,
68
+ encrypt ( passwordItem . password , clerkuser )
70
69
) ;
71
70
toast . success ( "Password created" ) ;
71
+ setPasswordItem ( initialPasswordItemState )
72
72
onClose ( ) ;
73
73
} catch ( error ) {
74
74
toast . error ( "Failed to create password" ) ;
@@ -77,6 +77,10 @@ export const CreatePasswordDialog = ({
77
77
}
78
78
} ;
79
79
80
+ const handleChange = ( e : ChangeEvent < HTMLInputElement > ) => {
81
+ setPasswordItem ( prevState => ( { ...prevState , [ e . target . name ] : e . target . value } ) )
82
+ }
83
+
80
84
return (
81
85
< Dialog open = { open } onOpenChange = { onClose } >
82
86
< DialogContent >
@@ -87,50 +91,54 @@ export const CreatePasswordDialog = ({
87
91
< div className = "relative" >
88
92
< Input
89
93
placeholder = "Name"
90
- value = { name }
91
- onChange = { ( e ) => setName ( e . target . value ) }
94
+ value = { passwordItem . name }
95
+ onChange = { handleChange }
92
96
maxLength = { 50 }
97
+ name = "name"
93
98
/>
94
- < div className = "mt-1 text-sm text-gray-500" > { name . length } / 50</ div >
99
+ < div className = "mt-1 text-sm text-gray-500" > { passwordItem . name . length } / 50</ div >
95
100
</ div >
96
101
< div className = "relative" >
97
102
< Input
98
103
placeholder = "Username"
99
- value = { username }
100
- onChange = { ( e ) => setUsername ( e . target . value ) }
104
+ value = { passwordItem . username }
105
+ onChange = { handleChange }
101
106
maxLength = { 30 }
107
+ name = "username"
102
108
/>
103
109
< div className = "mt-1 text-sm text-gray-500" >
104
- { username . length } / 30
110
+ { passwordItem . username . length } / 30
105
111
</ div >
106
112
</ div >
107
113
< div className = "relative" >
108
114
< Input
109
115
placeholder = "Website"
110
- value = { website }
111
- onChange = { ( e ) => setWebsite ( e . target . value ) }
116
+ value = { passwordItem . website }
117
+ onChange = { handleChange }
112
118
maxLength = { 1024 }
119
+ name = "website"
113
120
/>
114
121
< div className = "mt-1 text-sm text-gray-500" >
115
- { website . length } / 1024
122
+ { passwordItem . website . length } / 1024
116
123
</ div >
117
124
</ div >
118
125
< div className = "relative" >
119
126
< Input
120
127
placeholder = "Password"
121
- value = { password }
122
- onChange = { ( e ) => setPassword ( e . target . value ) }
128
+ value = { passwordItem . password }
129
+ onChange = { handleChange }
123
130
type = "password"
131
+ name = "password"
124
132
maxLength = { 128 }
125
133
/>
126
134
< div className = " mt-1 text-sm text-gray-500" >
127
- { password . length } / 128
135
+ { passwordItem . password . length } / 128
128
136
</ div >
129
137
</ div >
130
138
</ div >
131
139
< DialogFooter >
132
140
< div className = "mt-4 flex justify-end gap-2" >
133
- < Button variant = "outline" onClick = { onClose } >
141
+ < Button variant = "outline" onClick = { ( ) => onClose ( ) } >
134
142
Cancel
135
143
</ Button >
136
144
< Button onClick = { handleSave } >
0 commit comments