import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import { trpc } from '@documenso/trpc/react'; import { ZCreateApiTokenRequestSchema } from '@documenso/trpc/server/api-token-router/create-api-token.types'; import { CopyTextButton } from '@documenso/ui/components/common/copy-text-button'; import { Button } from '@documenso/ui/primitives/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@documenso/ui/primitives/dialog'; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@documenso/ui/primitives/form/form'; import { Input } from '@documenso/ui/primitives/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@documenso/ui/primitives/select'; import { useToast } from '@documenso/ui/primitives/use-toast'; import { zodResolver } from '@hookform/resolvers/zod'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import type * as DialogPrimitive from '@radix-ui/react-dialog'; import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { match } from 'ts-pattern'; import type { z } from 'zod'; import { useCurrentTeam } from '~/providers/team'; const NEVER_EXPIRE = 'NEVER' as const; export const EXPIRATION_DATES = { ONE_WEEK: msg`7 days`, ONE_MONTH: msg`1 month`, THREE_MONTHS: msg`3 months`, SIX_MONTHS: msg`6 months`, ONE_YEAR: msg`12 months`, [NEVER_EXPIRE]: msg`Never`, } as const; const ZCreateTokenFormSchema = ZCreateApiTokenRequestSchema.pick({ tokenName: true, expirationDate: true, }); type TCreateTokenFormSchema = z.infer; export type TokenCreateDialogProps = { trigger?: React.ReactNode; } & Omit; export const TokenCreateDialog = ({ trigger, ...props }: TokenCreateDialogProps) => { const { _ } = useLingui(); const { toast } = useToast(); const team = useCurrentTeam(); const [open, setOpen] = useState(false); const [createdToken, setCreatedToken] = useState(null); const form = useForm({ resolver: zodResolver(ZCreateTokenFormSchema), defaultValues: { tokenName: '', expirationDate: 'THREE_MONTHS', }, }); const { mutateAsync: createToken } = trpc.apiToken.create.useMutation(); const onSubmit = async ({ tokenName, expirationDate }: TCreateTokenFormSchema) => { try { const { token } = await createToken({ teamId: team.id, tokenName, expirationDate: expirationDate === NEVER_EXPIRE ? null : expirationDate, }); setCreatedToken(token); } catch (err) { const error = AppError.parseError(err); const errorMessage = match(error.code) .with(AppErrorCode.UNAUTHORIZED, () => msg`You do not have permission to create a token for this team.`) .otherwise(() => msg`Something went wrong. Please try again later.`); toast({ title: _(msg`An error occurred`), description: _(errorMessage), variant: 'destructive', duration: 5000, }); } }; useEffect(() => { if (open) { form.reset(); setCreatedToken(null); } }, [open, form]); return ( !form.formState.isSubmitting && setOpen(value)} {...props}> e.stopPropagation()} asChild> {trigger ?? ( )} { // Prevent losing the created token by accidentally clicking outside the dialog. if (createdToken) { event.preventDefault(); } }} > {createdToken ? ( <> Token created Copy your token now. For security reasons you will not be able to see it again.
toast({ title: _(msg`Token copied to clipboard`) })} />
) : ( <> Create API token Use API tokens to authenticate with the Documenso API.
( Name A name to help you identify this token later. )} /> ( Expires in )} />
)}
); };