"use client"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { Dialog } from "@calcom/features/components/controlled-dialog"; import { useCopy } from "@calcom/lib/hooks/useCopy"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { Alert } from "@calcom/ui/components/alert"; import { Badge } from "@calcom/ui/components/badge"; import { Button } from "@calcom/ui/components/button"; import { ConfirmationDialogContent, DialogClose, DialogContent, DialogFooter, } from "@calcom/ui/components/dialog"; import { showToast } from "@calcom/ui/components/toast"; import { Tooltip } from "@calcom/ui/components/tooltip"; import { Label, TextArea } from "@calcom/ui/components/form"; import type { OAuthClientCreateFormValues } from "../create/OAuthClientCreateModal"; import { OAuthClientFormFields } from "./OAuthClientFormFields"; type OAuthClientDetails = { clientId: string; name: string; purpose?: string | null; redirectUri?: string; websiteUrl?: string | null; logo?: string | null; status?: string; rejectionReason?: string | null; clientSecret?: string; isPkceEnabled?: boolean; clientType?: string; user?: { email: string; } | null; }; const OAuthClientDetailsDialog = ({ open, onOpenChange, client, onApprove, onReject, onUpdate, onDelete, isStatusChangePending, isUpdatePending, isDeletePending, }: { open: boolean; onOpenChange: (open: boolean) => void; client: OAuthClientDetails | null; onApprove?: (clientId: string) => void; onReject?: (input: { clientId: string; rejectionReason: string }) => void; onUpdate?: (input: { clientId: string; name: string; purpose: string; redirectUri: string; websiteUrl: string; logo: string; }) => void; onDelete?: (clientId: string) => void; isStatusChangePending?: boolean; isUpdatePending?: boolean; isDeletePending?: boolean; }) => { const { t } = useLocale(); const { copyToClipboard } = useCopy(); const [logo, setLogo] = useState(""); const [isDeleteConfirmOpen, setIsDeleteConfirmOpen] = useState(false); const [isRejectConfirmOpen, setIsRejectConfirmOpen] = useState(false); const [rejectionReason, setRejectionReason] = useState(""); const [showRejectionReasonError, setShowRejectionReasonError] = useState(false); const form = useForm({ defaultValues: { name: "", purpose: "", redirectUri: "", websiteUrl: "", logo: "", enablePkce: false, }, }); useEffect(() => { if (open) return; setIsDeleteConfirmOpen(false); setIsRejectConfirmOpen(false); setRejectionReason(""); setShowRejectionReasonError(false); }, [open]); useEffect(() => { if (!client) return; const enablePkce = client.isPkceEnabled ?? (client.clientType ? client.clientType.toUpperCase() === "PUBLIC" : false); const nextLogo = client.logo ?? ""; setLogo(nextLogo); form.reset({ name: client.name ?? "", purpose: client.purpose ?? "", redirectUri: client.redirectUri ?? "", websiteUrl: client.websiteUrl ?? "", logo: nextLogo, enablePkce, }); }, [client, form]); const status = client?.status; const showAdminActions = Boolean(onApprove) || Boolean(onReject); const isFormDisabled = showAdminActions; const canEdit = Boolean(onUpdate) && !isFormDisabled; const canDelete = Boolean(onDelete) && !showAdminActions; const handleConfirmReject = () => { if (!client) return; const trimmedReason = rejectionReason.trim(); if (trimmedReason.length === 0) { setShowRejectionReasonError(true); return; } onReject?.({ clientId: client.clientId, rejectionReason: trimmedReason }); setIsRejectConfirmOpen(false); setRejectionReason(""); setShowRejectionReasonError(false); }; const clientId = client?.clientId; const footerActions = (() => { const closeButton = ( {t("close")} ); if (showAdminActions) { const canReject = Boolean(onReject) && (status === "PENDING" || status === "APPROVED"); const canApprove = Boolean(onApprove) && (status === "PENDING" || status === "REJECTED"); return (
{closeButton} {canReject ? ( ) : null} {canApprove ? ( ) : null}
); } if (canEdit) { return (
{closeButton}
); } return
{closeButton}
; })(); return ( {client ? (
{ if (!canEdit) return; onUpdate?.({ clientId: client.clientId, name: values.name.trim() || "", purpose: values.purpose.trim() || "", redirectUri: values.redirectUri.trim() || "", websiteUrl: values.websiteUrl.trim() || "", logo: values.logo, }); })}> {status ? (
{t(getStatusBadgeVariant(status).labelKey)}
) : null} {status === "PENDING" ? ( ) : null} {status === "APPROVED" ? ( ) : null} {status === "REJECTED" && client.rejectionReason ? (

"{client.rejectionReason}".

{t("oauth_client_rejected_resubmit_info")}

} /> ) : null}
{t("client_id")}
{client.clientId}
{client.user?.email ? (
{t("owner")}
{client.user.email}
) : null} {canDelete ? (
{ if (!client) return; onDelete?.(client.clientId); }}> {isDeletePending ? t("deleting") : t("delete")} }>

{t("confirm_delete_oauth_client")}

) : null} {footerActions} {t("reject")} }>