1
+ "use client" ;
2
+
1
3
import { Button } from "@/components/ui/button" ;
2
4
import {
3
5
DropdownMenu ,
4
6
DropdownMenuContent ,
5
7
DropdownMenuItem ,
6
8
DropdownMenuTrigger ,
7
9
} from "@/components/ui/dropdown-menu" ;
10
+ import { cn } from "@/lib/utils" ;
8
11
import {
9
12
Eye ,
10
13
EyeOff ,
@@ -45,15 +48,17 @@ export const PasswordDetails: React.FC<PasswordDetailsProps> = ({
45
48
const [ isPasswordVisible , setIsPasswordVisible ] = useState ( false ) ;
46
49
47
50
return (
48
- < div className = "space-y-6" >
51
+ < div className = "space-y-6 mx-auto " >
49
52
< div className = "flex items-center justify-between" >
50
- < h2 className = "text-2xl font-bold text-gray-800" > { entry . name } </ h2 >
53
+ < h2 className = "text-2xl font-bold text-gray-800 dark:text-gray-200 truncate flex-1 mr-2" >
54
+ { entry . name }
55
+ </ h2 >
51
56
< DropdownMenu >
52
57
< DropdownMenuTrigger asChild >
53
58
< Button
54
59
variant = "ghost"
55
60
size = "icon"
56
- className = "bg-rose-50 hover:hover:bg-rose-100"
61
+ className = "bg-rose-50 hover:hover:bg-rose-100 dark:bg-rose-900 dark:hover:bg-rose-800 "
57
62
>
58
63
< MoreVertical className = "h-4 w-4" />
59
64
</ Button >
@@ -72,91 +77,72 @@ export const PasswordDetails: React.FC<PasswordDetailsProps> = ({
72
77
</ div >
73
78
74
79
< div >
75
- < div className = "flex items-center justify-between rounded-t-xl border border-gray-200 bg-gray-50/50 p-4" >
76
- < Tooltip >
77
- < TooltipContent > Copy</ TooltipContent >
78
- < TooltipTrigger
79
- onClick = { ( ) => {
80
- navigator . clipboard . writeText ( entry . website ) ;
81
- toast . success ( "Copied website succesfully" ) ;
82
- } }
83
- >
84
- < div className = "flex items-center space-x-2" >
85
- < Globe className = "h-4 w-4" />
86
- < span className = "text-gray-900" > { entry . website } </ span >
87
- </ div >
88
- </ TooltipTrigger >
89
- </ Tooltip >
90
-
80
+ < DetailItem
81
+ icon = { < Globe className = "h-4 w-4 flex-shrink-0" /> }
82
+ value = { entry . website }
83
+ onCopy = { ( ) => {
84
+ navigator . clipboard . writeText ( entry . website ) ;
85
+ toast . success ( "Copied website successfully" ) ;
86
+ } }
87
+ className = "rounded-tl-xl rounded-tr-xl"
88
+ >
91
89
< a href = { entry . website } target = "_blank" rel = "noopener noreferrer" >
92
90
< Button variant = "ghost" size = "icon" className = "p-0" >
93
91
< SquareArrowOutUpRight className = "h-4 w-4" />
94
92
</ Button >
95
93
</ a >
96
- </ div >
97
-
98
- < div className = "flex items-center justify-between border border-gray-200 bg-gray-50/50 px-4 py-6" >
99
- < Tooltip >
100
- < TooltipContent > Copy</ TooltipContent >
101
- < TooltipTrigger
102
- onClick = { ( ) => {
103
- navigator . clipboard . writeText ( entry . username ) ;
104
- toast . success ( "Copied username succesfully" ) ;
105
- } }
106
- >
107
- < div className = "flex items-center space-x-2" >
108
- < User className = "h-4 w-4" />
109
- < span className = "text-gray-900" > { entry . username } </ span >
110
- </ div >
111
- </ TooltipTrigger >
112
- </ Tooltip >
113
- </ div >
94
+ </ DetailItem >
114
95
115
- < div className = "flex items-center justify-between rounded-b-xl border border-gray-200 bg-gray-50/50 p-4" >
116
- < Tooltip >
117
- < TooltipContent > Copy</ TooltipContent >
118
- < TooltipTrigger
119
- onClick = { ( ) => {
120
- navigator . clipboard . writeText ( entry . password ) ;
121
- toast . success ( "Copied password succesfully" ) ;
122
- } }
123
- >
124
- < div className = "flex items-center space-x-2" >
125
- < Lock className = "h-4 w-4" />
126
- < span >
127
- { isPasswordVisible
128
- ? entry . password
129
- : "•" . repeat ( entry . password . length ) }
130
- </ span >
131
- </ div >
132
- </ TooltipTrigger >
133
- </ Tooltip >
96
+ < DetailItem
97
+ icon = { < User className = "h-4 w-4 flex-shrink-0" /> }
98
+ value = { entry . username }
99
+ onCopy = { ( ) => {
100
+ navigator . clipboard . writeText ( entry . username ) ;
101
+ toast . success ( "Copied username successfully" ) ;
102
+ } }
103
+ className = "py-6"
104
+ />
134
105
106
+ < DetailItem
107
+ icon = { < Lock className = "h-4 w-4 flex-shrink-0" /> }
108
+ value = {
109
+ isPasswordVisible
110
+ ? entry . password
111
+ : "•" . repeat ( entry . password . length )
112
+ }
113
+ onCopy = { ( ) => {
114
+ navigator . clipboard . writeText ( entry . password ) ;
115
+ toast . success ( "Copied password successfully" ) ;
116
+ } }
117
+ className = "rounded-br-xl rounded-bl-xl"
118
+ >
135
119
< Button
136
120
variant = "ghost"
137
121
onClick = { ( ) => setIsPasswordVisible ( ! isPasswordVisible ) }
138
122
className = "p-0"
139
- size = { "icon" }
123
+ size = "icon"
140
124
>
141
125
{ isPasswordVisible ? (
142
126
< EyeOff className = "h-4 w-4" />
143
127
) : (
144
128
< Eye className = "h-4 w-4" />
145
129
) }
146
130
</ Button >
147
- </ div >
131
+ </ DetailItem >
148
132
</ div >
149
133
150
134
< div className = "space-y-2" >
151
- < h3 className = "text-lg font-medium text-gray-500" > History</ h3 > { " " }
152
- < div className = "space-y-3 rounded-xl border border-gray-200 bg-gray-50/50 p-4" >
135
+ < h3 className = "text-lg font-medium text-gray-500 dark:text-gray-400" >
136
+ History
137
+ </ h3 >
138
+ < div className = "space-y-3 rounded-xl border border-gray-200 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-800/50 p-4" >
153
139
{ [ "Created" , "Last modified" , "Last access" ] . map ( ( label ) => (
154
140
< div
155
141
key = { label }
156
142
className = "flex items-center justify-between text-xs"
157
143
>
158
- < span className = "text-gray-500" > { label } </ span >
159
- < span className = "font-medium text-gray-900" >
144
+ < span className = "text-gray-500 dark:text-gray-400 " > { label } </ span >
145
+ < span className = "font-medium text-gray-900 dark:text-gray-100 " >
160
146
{ label === "Last access"
161
147
? new Date ( entry . lastAccess ) . toLocaleString ( )
162
148
: label === "Last modified"
@@ -172,3 +158,40 @@ export const PasswordDetails: React.FC<PasswordDetailsProps> = ({
172
158
</ div >
173
159
) ;
174
160
} ;
161
+
162
+ interface DetailItemProps {
163
+ icon : React . ReactNode ;
164
+ value : string ;
165
+ onCopy : ( ) => void ;
166
+ children ?: React . ReactNode ;
167
+ className ?: string ;
168
+ }
169
+
170
+ const DetailItem : React . FC < DetailItemProps > = ( {
171
+ icon,
172
+ value,
173
+ onCopy,
174
+ children,
175
+ className,
176
+ } ) => (
177
+ < div
178
+ className = { cn (
179
+ "flex items-center justify-between border border-gray-200 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-800/50 p-4" ,
180
+ className
181
+ ) }
182
+ >
183
+ < Tooltip >
184
+ < TooltipContent > Copy</ TooltipContent >
185
+ < TooltipTrigger
186
+ onClick = { onCopy }
187
+ className = "flex items-center space-x-2 max-w-[calc(100%-2rem)] overflow-hidden"
188
+ >
189
+ { icon }
190
+ < span className = "text-gray-900 dark:text-gray-100 truncate" >
191
+ { value }
192
+ </ span >
193
+ </ TooltipTrigger >
194
+ </ Tooltip >
195
+ { children }
196
+ </ div >
197
+ ) ;
0 commit comments