import classNames from "classnames"; import { debounce } from "lodash"; import { MutableRefObject, useCallback, useEffect, useState } from "react"; import { fetchUsername } from "@calcom/lib/fetchUsername"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { TRPCClientErrorLike } from "@calcom/trpc/client"; import { trpc } from "@calcom/trpc/react"; import { AppRouter } from "@calcom/trpc/server/routers/_app"; import Button from "@calcom/ui/Button"; import { Dialog, DialogClose, DialogContent, DialogHeader } from "@calcom/ui/Dialog"; import { Icon } from "@calcom/ui/Icon"; import { Input, Label } from "@calcom/ui/v2"; interface ICustomUsernameProps { currentUsername: string | undefined; setCurrentUsername: (value: string | undefined) => void; inputUsernameValue: string | undefined; usernameRef: MutableRefObject; setInputUsernameValue: (value: string) => void; onSuccessMutation?: () => void; onErrorMutation?: (error: TRPCClientErrorLike) => void; } const UsernameTextfield = (props: ICustomUsernameProps) => { const { t } = useLocale(); const { currentUsername, setCurrentUsername, inputUsernameValue, setInputUsernameValue, usernameRef, onSuccessMutation, onErrorMutation, } = props; const [usernameIsAvailable, setUsernameIsAvailable] = useState(false); const [markAsError, setMarkAsError] = useState(false); const [openDialogSaveUsername, setOpenDialogSaveUsername] = useState(false); const debouncedApiCall = useCallback( debounce(async (username) => { const { data } = await fetchUsername(username); setMarkAsError(!data.available); setUsernameIsAvailable(data.available); }, 150), [] ); useEffect(() => { if (currentUsername !== inputUsernameValue) { debouncedApiCall(inputUsernameValue); } else if (inputUsernameValue === "") { setMarkAsError(false); setUsernameIsAvailable(false); } else { setUsernameIsAvailable(false); } }, [inputUsernameValue]); const utils = trpc.useContext(); const updateUsername = trpc.useMutation("viewer.updateProfile", { onSuccess: async () => { onSuccessMutation && (await onSuccessMutation()); setCurrentUsername(inputUsernameValue); setOpenDialogSaveUsername(false); }, onError: (error) => { onErrorMutation && onErrorMutation(error); }, async onSettled() { await utils.invalidateQueries(["viewer.public.i18n"]); }, }); const ActionButtons = (props: { index: string }) => { const { index } = props; return usernameIsAvailable && currentUsername !== inputUsernameValue ? (
) : ( <> ); }; return (
{process.env.NEXT_PUBLIC_WEBSITE_URL.replace("https://", "").replace("http://", "")}/
{ event.preventDefault(); setInputUsernameValue(event.target.value); }} data-testid="username-input" /> {currentUsername !== inputUsernameValue && (
{usernameIsAvailable ? : <>}
)}
{markAsError &&

Username is already taken

} {usernameIsAvailable && currentUsername !== inputUsernameValue && (
)}

{t("current_username")}

{currentUsername}

{t("new_username")}

{inputUsernameValue}

); }; export { UsernameTextfield };