@@ -231,9 +231,11 @@ export function CardsContent() {
231231 < Table >
232232 < TableHeader >
233233 < TableRow >
234- < TableHead className = "w-[150px ]" > { translate ( "name" , "cards" , { default : "Name" } ) } </ TableHead >
234+ < TableHead className = "w-[200px ]" > { translate ( "name" , "cards" , { default : "Name" } ) } </ TableHead >
235235 < TableHead > { translate ( "card_number" , "cards" , { default : "Card Number" } ) } </ TableHead >
236+ < TableHead > { translate ( "card_holder" , "cards" , { default : "Card Holder" } ) } </ TableHead >
236237 < TableHead > { translate ( "expiry" , "cards" , { default : "Expiry" } ) } </ TableHead >
238+ < TableHead > { translate ( "cvv" , "cards" , { default : "CVV" } ) } </ TableHead >
237239 < TableHead > { translate ( "tags" , "cards" , { default : "Tags" } ) } </ TableHead >
238240 < TableHead className = "text-right" > { translate ( "actions" , "cards" , { default : "Actions" } ) } </ TableHead >
239241 </ TableRow >
@@ -242,14 +244,128 @@ export function CardsContent() {
242244 < TableBody >
243245 { cardsToDisplay . map ( ( card ) => (
244246 < TableRow key = { card . doc_id } >
245- < TableCell className = "font-medium" > { card . title } </ TableCell >
247+ < TableCell className = "font-medium" >
248+ < div className = "flex items-center gap-3" >
249+ < div className = "flex h-8 w-8 items-center justify-center rounded-full bg-accent" >
250+ < CreditCard className = "h-4 w-4" />
251+ </ div >
252+ < span > { card . title } </ span >
253+ </ div >
254+ </ TableCell >
255+ < TableCell >
256+ < div className = "flex items-center gap-2" >
257+ < div className = "relative max-w-[120px] truncate font-mono" >
258+ { viewSensitiveData === card . doc_id ? formatCardNumber ( card . number ) : "•••• •••• •••• ••••" }
259+ </ div >
260+ < TooltipProvider >
261+ < Tooltip >
262+ < TooltipTrigger asChild >
263+ < Button
264+ variant = "ghost"
265+ size = "icon"
266+ className = "h-8 w-8"
267+ onClick = { ( ) => toggleDataVisibility ( card . doc_id ) }
268+ >
269+ { viewSensitiveData === card . doc_id ? (
270+ < EyeOff className = "h-4 w-4" />
271+ ) : (
272+ < Eye className = "h-4 w-4" />
273+ ) }
274+ </ Button >
275+ </ TooltipTrigger >
276+ < TooltipContent >
277+ { viewSensitiveData === card . doc_id
278+ ? translate ( "hide_card_number" , "cards" )
279+ : translate ( "show_card_number" , "cards" ) }
280+ </ TooltipContent >
281+ </ Tooltip >
282+ </ TooltipProvider >
283+ < TooltipProvider >
284+ < Tooltip >
285+ < TooltipTrigger asChild >
286+ < Button
287+ variant = "ghost"
288+ size = "icon"
289+ className = "h-8 w-8"
290+ onClick = { ( ) => copyToClipboard ( card . doc_id , "number" , card . number ) }
291+ >
292+ { copiedField ?. id === card . doc_id && copiedField ?. field === "number" ? (
293+ < Check className = "h-4 w-4 text-green-500" />
294+ ) : (
295+ < Copy className = "h-4 w-4" />
296+ ) }
297+ </ Button >
298+ </ TooltipTrigger >
299+ < TooltipContent >
300+ { copiedField ?. id === card . doc_id && copiedField ?. field === "number"
301+ ? translate ( "copied" , "cards" )
302+ : translate ( "copy_card_number" , "cards" ) }
303+ </ TooltipContent >
304+ </ Tooltip >
305+ </ TooltipProvider >
306+ </ div >
307+ </ TableCell >
246308 < TableCell >
247309 < div className = "flex items-center gap-2" >
248- < CreditCard className = "h-4 w-4 text-muted-foreground" />
249- < span > { card . card_holder_name } </ span >
310+ < div className = "relative max-w-[120px] truncate" >
311+ { card . card_holder_name }
312+ </ div >
313+ < TooltipProvider >
314+ < Tooltip >
315+ < TooltipTrigger asChild >
316+ < Button
317+ variant = "ghost"
318+ size = "icon"
319+ className = "h-8 w-8"
320+ onClick = { ( ) => copyToClipboard ( card . doc_id , "card_holder" , card . card_holder_name ) }
321+ >
322+ { copiedField ?. id === card . doc_id && copiedField ?. field === "card_holder" ? (
323+ < Check className = "h-4 w-4 text-green-500" />
324+ ) : (
325+ < Copy className = "h-4 w-4" />
326+ ) }
327+ </ Button >
328+ </ TooltipTrigger >
329+ < TooltipContent >
330+ { copiedField ?. id === card . doc_id && copiedField ?. field === "card_holder"
331+ ? translate ( "copied" , "cards" )
332+ : translate ( "copy_card_holder" , "cards" ) }
333+ </ TooltipContent >
334+ </ Tooltip >
335+ </ TooltipProvider >
250336 </ div >
251337 </ TableCell >
252338 < TableCell > { formatExpiryDate ( card . expiry_month , card . expiry_year ) } </ TableCell >
339+ < TableCell >
340+ < div className = "flex items-center gap-2" >
341+ < div className = "relative max-w-[120px] truncate font-mono" >
342+ { viewSensitiveData === card . doc_id ? card . cvv : "•••" }
343+ </ div >
344+ < TooltipProvider >
345+ < Tooltip >
346+ < TooltipTrigger asChild >
347+ < Button
348+ variant = "ghost"
349+ size = "icon"
350+ className = "h-8 w-8"
351+ onClick = { ( ) => copyToClipboard ( card . doc_id , "cvv" , card . cvv ) }
352+ >
353+ { copiedField ?. id === card . doc_id && copiedField ?. field === "cvv" ? (
354+ < Check className = "h-4 w-4 text-green-500" />
355+ ) : (
356+ < Copy className = "h-4 w-4" />
357+ ) }
358+ </ Button >
359+ </ TooltipTrigger >
360+ < TooltipContent >
361+ { copiedField ?. id === card . doc_id && copiedField ?. field === "cvv"
362+ ? translate ( "copied" , "cards" )
363+ : translate ( "copy_cvv" , "cards" ) }
364+ </ TooltipContent >
365+ </ Tooltip >
366+ </ TooltipProvider >
367+ </ div >
368+ </ TableCell >
253369 < TableCell >
254370 < div className = "flex flex-wrap gap-1" >
255371 { card . tags ?. map ( ( tag ) => (
@@ -282,8 +398,8 @@ export function CardsContent() {
282398 ) : (
283399 < TableBody >
284400 < TableRow >
285- < TableCell colSpan = { 5 } className = "h-24 text-center" >
286- < div className = "flex flex-col items-center justify-center" >
401+ < TableCell colSpan = { 7 } className = "h-24 text-center" >
402+ < div className = "flex flex-col items-center justify-center w-full mx-auto " >
287403 < p className = "text-muted-foreground" >
288404 { searchQuery
289405 ? translate ( "no_matching_cards" , "cards" , { default : "No matching cards found" } )
0 commit comments