"use client"; import { useState } from "react"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import { EmptyScreen } from "@calcom/ui/components/empty-screen"; import { showToast } from "@calcom/ui/components/toast"; import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader"; import type { OAuthClientCreateFormValues } from "../oauth/create/OAuthClientCreateModal"; import { OAuthClientCreateDialog } from "../oauth/create/OAuthClientCreateModal"; import { OAuthClientPreviewDialog } from "../oauth/create/OAuthClientPreviewDialog"; import { OAuthClientDetailsDialog, type OAuthClientDetails } from "../oauth/view/OAuthClientDetailsDialog"; import { OAuthClientsList } from "../oauth/OAuthClientsList"; import { NewOAuthClientButton } from "../oauth/create/NewOAuthClientButton"; import { OAuthClientsSkeleton } from "./oauth-clients-skeleton"; const OAuthClientsView = () => { const { t } = useLocale(); const utils = trpc.useUtils(); const [isCreatingClient, setIsCreatingClient] = useState(false); const [submittedClient, setSubmittedClient] = useState(null); const [selectedClient, setSelectedClient] = useState(null); const { data: oAuthClients, isLoading } = trpc.viewer.oAuth.listUserClients.useQuery(); const submitForReviewMutation = trpc.viewer.oAuth.submitClientForReview.useMutation({ onSuccess: async (data) => { setSubmittedClient({ clientId: data.clientId, name: data.name, purpose: data.purpose ?? "", clientSecret: data.clientSecret, status: data.status, isPkceEnabled: data.isPkceEnabled, }); showToast(t("oauth_client_submitted"), "success"); utils.viewer.oAuth.listUserClients.invalidate(); }, onError: (error) => { showToast(`${t("oauth_client_submit_error")}: ${error.message}`, "error"); }, }); const deleteClientMutation = trpc.viewer.oAuth.deleteClient.useMutation({ onSuccess: async () => { showToast(t("oauth_client_deletion_message"), "success"); setSelectedClient(null); utils.viewer.oAuth.listUserClients.invalidate(); }, onError: (error) => { showToast(error.message || t("error"), "error"); }, }); const updateClientMutation = trpc.viewer.oAuth.updateClient.useMutation({ onSuccess: async (data) => { showToast(t("oauth_client_updated_successfully"), "success"); setSelectedClient((prev) => { if (!prev) return prev; if (prev.clientId !== data.clientId) return prev; return { ...prev, name: data.name, purpose: data.purpose, redirectUri: data.redirectUri, websiteUrl: data.websiteUrl, logo: data.logo, status: data.status, rejectionReason: data.rejectionReason, }; }); utils.viewer.oAuth.listUserClients.invalidate(); }, onError: (error) => { showToast(`${t("updating_oauth_client_error")}: ${error.message}`, "error"); }, }); const handleSubmit = (values: OAuthClientCreateFormValues) => { submitForReviewMutation.mutate({ name: values.name, purpose: values.purpose, redirectUri: values.redirectUri, websiteUrl: values.websiteUrl, logo: values.logo, enablePkce: values.enablePkce, }); }; const handleCloseCreateDialog = () => { setIsCreatingClient(false); setSubmittedClient(null); }; const handleCloseDetailsDialog = () => { setSelectedClient(null); }; if (isLoading) { return ; } const newOAuthClientButton = ( setIsCreatingClient(true)} /> ); return (
{oAuthClients && oAuthClients.length > 0 ? (
({ clientId: client.clientId, name: client.name, purpose: client.purpose, redirectUri: client.redirectUri, websiteUrl: client.websiteUrl, logo: client.logo, status: client.status, rejectionReason: client.rejectionReason, clientType: client.clientType, }))} onSelectClient={(client) => setSelectedClient(client)} />
) : ( )}
{submittedClient ? ( ) : ( )} !open && handleCloseDetailsDialog()} client={selectedClient} onUpdate={(values) => { updateClientMutation.mutate({ clientId: values.clientId, name: values.name, purpose: values.purpose, redirectUri: values.redirectUri, websiteUrl: values.websiteUrl, logo: values.logo, }); }} onDelete={(clientId) => { deleteClientMutation.mutate({ clientId }); }} isUpdatePending={updateClientMutation.isPending} isDeletePending={deleteClientMutation.isPending} />
); }; export default OAuthClientsView;