@@ -4,7 +4,6 @@ import { useState } from 'react'
44import { z } from 'zod'
55import { useForm } from 'react-hook-form'
66import { zodResolver } from '@hookform/resolvers/zod'
7- import { format } from 'date-fns'
87import { Copy , Check , Loader2 } from 'lucide-react'
98import { toast } from 'sonner'
109import { Button } from '@/components/ui/button'
@@ -28,13 +27,12 @@ import {
2827import { Input } from '@/components/ui/input'
2928import { Switch } from '@/components/ui/switch'
3029import { Label } from '@/components/ui/label'
31- import type { ApiKey } from '@/lib/api-keys-api'
3230import {
3331 createApiKey ,
3432 updateApiKey ,
33+ type ApiKey ,
3534 type CreateApiKeyResponse ,
3635} from '@/lib/api-keys-api'
37- import { cn } from '@/lib/utils'
3836
3937const createFormSchema = z . object ( {
4038 name : z . string ( ) . optional ( ) ,
@@ -94,8 +92,6 @@ export function ApiKeysActionDialog({
9492 } ,
9593 } )
9694
97- const form = isEdit ? updateForm : createForm
98-
9995 const onSubmit = async ( values : CreateFormValues | UpdateFormValues ) => {
10096 setIsLoading ( true )
10197 try {
@@ -107,7 +103,7 @@ export function ApiKeysActionDialog({
107103 expiresAt : updateValues . expiresAt === '' ? null : updateValues . expiresAt || undefined ,
108104 } )
109105 toast . success ( 'API key atualizada com sucesso!' )
110- form . reset ( )
106+ updateForm . reset ( )
111107 onOpenChange ( false )
112108 onSuccess ( )
113109 } else {
@@ -164,7 +160,11 @@ export function ApiKeysActionDialog({
164160 }
165161
166162 const handleClose = ( ) => {
167- form . reset ( )
163+ if ( isEdit ) {
164+ updateForm . reset ( )
165+ } else {
166+ createForm . reset ( )
167+ }
168168 setCreatedApiKey ( null )
169169 setCopied ( false )
170170 setCopiedCurl ( false )
@@ -263,32 +263,32 @@ export function ApiKeysActionDialog({
263263 : 'Crie uma nova API key para sua organização.' }
264264 </ DialogDescription >
265265 </ DialogHeader >
266- < Form { ...form } >
267- < form onSubmit = { form . handleSubmit ( onSubmit ) } className = 'space-y-4' >
268- < FormField
269- control = { form . control }
270- name = 'name'
271- render = { ( { field } ) => (
272- < FormItem >
273- < FormLabel > Nome (opcional)</ FormLabel >
274- < FormControl >
275- < Input
276- placeholder = 'Ex: API Key Produção'
277- { ...field }
278- value = { field . value || '' }
279- />
280- </ FormControl >
281- < FormDescription >
282- Um nome descritivo para identificar esta API key.
283- </ FormDescription >
284- < FormMessage />
285- </ FormItem >
286- ) }
287- />
266+ { isEdit ? (
267+ < Form { ...updateForm } >
268+ < form onSubmit = { updateForm . handleSubmit ( onSubmit ) } className = 'space-y-4' >
269+ < FormField
270+ control = { updateForm . control }
271+ name = 'name'
272+ render = { ( { field } ) => (
273+ < FormItem >
274+ < FormLabel > Nome (opcional)</ FormLabel >
275+ < FormControl >
276+ < Input
277+ placeholder = 'Ex: API Key Produção'
278+ { ...field }
279+ value = { field . value || '' }
280+ />
281+ </ FormControl >
282+ < FormDescription >
283+ Um nome descritivo para identificar esta API key.
284+ </ FormDescription >
285+ < FormMessage />
286+ </ FormItem >
287+ ) }
288+ />
288289
289- { isEdit && (
290290 < FormField
291- control = { form . control }
291+ control = { updateForm . control }
292292 name = 'isActive'
293293 render = { ( { field } ) => (
294294 < FormItem className = 'flex flex-row items-center justify-between rounded-lg border p-4' >
@@ -307,77 +307,162 @@ export function ApiKeysActionDialog({
307307 </ FormItem >
308308 ) }
309309 />
310- ) }
311310
312- < FormField
313- control = { form . control }
314- name = 'expiresAt'
315- render = { ( { field } ) => {
316- // Converter para formato datetime-local
317- const getValue = ( ) => {
318- if ( ! field . value ) return ''
319- try {
320- const date = new Date ( field . value )
321- // Ajustar para timezone local
322- const year = date . getFullYear ( )
323- const month = String ( date . getMonth ( ) + 1 ) . padStart ( 2 , '0' )
324- const day = String ( date . getDate ( ) ) . padStart ( 2 , '0' )
325- const hours = String ( date . getHours ( ) ) . padStart ( 2 , '0' )
326- const minutes = String ( date . getMinutes ( ) ) . padStart ( 2 , '0' )
327- return `${ year } -${ month } -${ day } T${ hours } :${ minutes } `
328- } catch {
329- return ''
311+ < FormField
312+ control = { updateForm . control }
313+ name = 'expiresAt'
314+ render = { ( { field } ) => {
315+ // Converter para formato datetime-local
316+ const getValue = ( ) => {
317+ if ( ! field . value ) return ''
318+ try {
319+ const date = new Date ( field . value )
320+ // Ajustar para timezone local
321+ const year = date . getFullYear ( )
322+ const month = String ( date . getMonth ( ) + 1 ) . padStart ( 2 , '0' )
323+ const day = String ( date . getDate ( ) ) . padStart ( 2 , '0' )
324+ const hours = String ( date . getHours ( ) ) . padStart ( 2 , '0' )
325+ const minutes = String ( date . getMinutes ( ) ) . padStart ( 2 , '0' )
326+ return `${ year } -${ month } -${ day } T${ hours } :${ minutes } `
327+ } catch {
328+ return ''
329+ }
330330 }
331- }
332331
333- return (
332+ return (
333+ < FormItem >
334+ < FormLabel > Data de Expiração (opcional)</ FormLabel >
335+ < FormControl >
336+ < Input
337+ type = 'datetime-local'
338+ value = { getValue ( ) }
339+ onChange = { ( e ) => {
340+ const value = e . target . value
341+ if ( value ) {
342+ // Converter para ISO string
343+ const date = new Date ( value )
344+ field . onChange ( date . toISOString ( ) )
345+ } else {
346+ field . onChange ( null )
347+ }
348+ } }
349+ />
350+ </ FormControl >
351+ < FormDescription >
352+ Deixe em branco para remover a data de expiração.
353+ </ FormDescription >
354+ < FormMessage />
355+ </ FormItem >
356+ )
357+ } }
358+ />
359+
360+ < DialogFooter >
361+ < Button
362+ type = 'button'
363+ variant = 'outline'
364+ onClick = { handleClose }
365+ disabled = { isLoading }
366+ >
367+ Cancelar
368+ </ Button >
369+ < Button type = 'submit' disabled = { isLoading } >
370+ { isLoading && < Loader2 className = 'mr-2 h-4 w-4 animate-spin' /> }
371+ Salvar Alterações
372+ </ Button >
373+ </ DialogFooter >
374+ </ form >
375+ </ Form >
376+ ) : (
377+ < Form { ...createForm } >
378+ < form onSubmit = { createForm . handleSubmit ( onSubmit ) } className = 'space-y-4' >
379+ < FormField
380+ control = { createForm . control }
381+ name = 'name'
382+ render = { ( { field } ) => (
334383 < FormItem >
335- < FormLabel >
336- Data de Expiração { isEdit ? '(opcional)' : '(opcional)' }
337- </ FormLabel >
384+ < FormLabel > Nome (opcional)</ FormLabel >
338385 < FormControl >
339386 < Input
340- type = 'datetime-local'
341- value = { getValue ( ) }
342- onChange = { ( e ) => {
343- const value = e . target . value
344- if ( value ) {
345- // Converter para ISO string
346- const date = new Date ( value )
347- field . onChange ( date . toISOString ( ) )
348- } else {
349- field . onChange ( isEdit ? null : undefined )
350- }
351- } }
387+ placeholder = 'Ex: API Key Produção'
388+ { ...field }
389+ value = { field . value || '' }
352390 />
353391 </ FormControl >
354392 < FormDescription >
355- { isEdit
356- ? 'Deixe em branco para remover a data de expiração.'
357- : 'Deixe em branco para que a API key nunca expire.' }
393+ Um nome descritivo para identificar esta API key.
358394 </ FormDescription >
359395 < FormMessage />
360396 </ FormItem >
361- )
362- } }
363- />
397+ ) }
398+ />
399+
400+ < FormField
401+ control = { createForm . control }
402+ name = 'expiresAt'
403+ render = { ( { field } ) => {
404+ // Converter para formato datetime-local
405+ const getValue = ( ) => {
406+ if ( ! field . value ) return ''
407+ try {
408+ const date = new Date ( field . value )
409+ // Ajustar para timezone local
410+ const year = date . getFullYear ( )
411+ const month = String ( date . getMonth ( ) + 1 ) . padStart ( 2 , '0' )
412+ const day = String ( date . getDate ( ) ) . padStart ( 2 , '0' )
413+ const hours = String ( date . getHours ( ) ) . padStart ( 2 , '0' )
414+ const minutes = String ( date . getMinutes ( ) ) . padStart ( 2 , '0' )
415+ return `${ year } -${ month } -${ day } T${ hours } :${ minutes } `
416+ } catch {
417+ return ''
418+ }
419+ }
364420
365- < DialogFooter >
366- < Button
367- type = 'button'
368- variant = 'outline'
369- onClick = { handleClose }
370- disabled = { isLoading }
371- >
372- Cancelar
373- </ Button >
374- < Button type = 'submit' disabled = { isLoading } >
375- { isLoading && < Loader2 className = 'mr-2 h-4 w-4 animate-spin' /> }
376- { isEdit ? 'Salvar Alterações' : 'Criar API Key' }
377- </ Button >
378- </ DialogFooter >
379- </ form >
380- </ Form >
421+ return (
422+ < FormItem >
423+ < FormLabel > Data de Expiração (opcional)</ FormLabel >
424+ < FormControl >
425+ < Input
426+ type = 'datetime-local'
427+ value = { getValue ( ) }
428+ onChange = { ( e ) => {
429+ const value = e . target . value
430+ if ( value ) {
431+ // Converter para ISO string
432+ const date = new Date ( value )
433+ field . onChange ( date . toISOString ( ) )
434+ } else {
435+ field . onChange ( undefined )
436+ }
437+ } }
438+ />
439+ </ FormControl >
440+ < FormDescription >
441+ Deixe em branco para que a API key nunca expire.
442+ </ FormDescription >
443+ < FormMessage />
444+ </ FormItem >
445+ )
446+ } }
447+ />
448+
449+ < DialogFooter >
450+ < Button
451+ type = 'button'
452+ variant = 'outline'
453+ onClick = { handleClose }
454+ disabled = { isLoading }
455+ >
456+ Cancelar
457+ </ Button >
458+ < Button type = 'submit' disabled = { isLoading } >
459+ { isLoading && < Loader2 className = 'mr-2 h-4 w-4 animate-spin' /> }
460+ Criar API Key
461+ </ Button >
462+ </ DialogFooter >
463+ </ form >
464+ </ Form >
465+ ) }
381466 </ DialogContent >
382467 </ Dialog >
383468 )
0 commit comments