* added lockedSMS to future routes * add orgMigrations routes to future * correct metadata * small fix * add orgMigrations to future * Move components to client components * Remove tRPC element from edit user RSC * Get username for meta * Remove suspense query * Remove orgMigrations from app router * Type fix * Revert "Remove suspense query" This reverts commit eadd814f6e4a5d6856d9218342b7909c22fe62c6. * Handle suspenseQuery in app router * User edit page, fetch data server side * Update yarn.lock * Export getFixedT * Set PageWrapper as root layout for settings * Settings Layout accepts strings for shell heading * Add OOO to app router settings * Refactor layout for my-account pages * Remove instances of pages router from my-account * Refactor security pages * Add billing to app router * Add admin API link to layout * Add api keys page * Webhooks WIP * Refactor SettingsHeader to client component * Add webhook pages * Refactor API keys page * Add admin app page * Type fix * fix types * fix developer/webhooks/[id] param value type error * remove unnecessary code * do not pass t prop to CreateNewWebhookButton * fix type errors in webhook-edit-view * fix the remaining type errors * do not use prisma directly in generateMetadata * remove use client if unnecessary * Remove unused shell heading from SettingsLayoutAppDir * improve metadata * fix billing page * fix import in settings/teams * Use next `notFound()` * fix type check * fix type check * remove unused code * Fix calendar setting page * Separate settings pages into route groups * Refactor admin settings pages * Remove meta instance from billing page route * Update settings layoutAppDir * Refactor developer settings pages * Refactor out of office * Refactor my account settings * Refactor admin api page * Refactor security pages * Type fix * fix styling in settings layout --------- Co-authored-by: Somay Chauhan <somaychauhan98@gmail.com> Co-authored-by: Omar López <zomars@me.com> Co-authored-by: Benny Joo <sldisek783@gmail.com>
128 lines
3.9 KiB
TypeScript
128 lines
3.9 KiB
TypeScript
import { useState } from "react";
|
|
import type { UseFormReturn } from "react-hook-form";
|
|
|
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
|
import {
|
|
Badge,
|
|
TextField,
|
|
Dropdown,
|
|
DropdownItem,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger,
|
|
Button,
|
|
InputError,
|
|
} from "@calcom/ui";
|
|
|
|
import type { FormValues } from "~/settings/my-account/profile-view";
|
|
|
|
type CustomEmailTextFieldProps = {
|
|
formMethods: UseFormReturn<FormValues>;
|
|
formMethodFieldName: keyof FormValues;
|
|
errorMessage: string;
|
|
emailVerified: boolean;
|
|
emailPrimary: boolean;
|
|
dataTestId: string;
|
|
handleChangePrimary: () => void;
|
|
handleVerifyEmail: () => void;
|
|
handleItemDelete: () => void;
|
|
};
|
|
|
|
const CustomEmailTextField = ({
|
|
formMethods,
|
|
formMethodFieldName,
|
|
errorMessage,
|
|
emailVerified,
|
|
emailPrimary,
|
|
dataTestId,
|
|
handleChangePrimary,
|
|
handleVerifyEmail,
|
|
handleItemDelete,
|
|
}: CustomEmailTextFieldProps) => {
|
|
const { t } = useLocale();
|
|
const [inputFocus, setInputFocus] = useState(false);
|
|
|
|
return (
|
|
<>
|
|
<div
|
|
className={`border-default mt-2 flex items-center rounded-md border ${
|
|
inputFocus ? "ring-brand-default border-neutral-300 ring-2" : ""
|
|
}`}>
|
|
<TextField
|
|
{...formMethods.register(formMethodFieldName)}
|
|
label=""
|
|
containerClassName="flex flex-1 items-center"
|
|
className="mb-0 border-none outline-none focus:ring-0"
|
|
data-testid={dataTestId}
|
|
onFocus={() => setInputFocus(true)}
|
|
onBlur={() => setInputFocus(false)}
|
|
/>
|
|
<div className="flex items-center pr-2">
|
|
{emailPrimary && (
|
|
<Badge variant="blue" size="sm" data-testid={`${dataTestId}-primary-badge`}>
|
|
{t("primary")}
|
|
</Badge>
|
|
)}
|
|
{!emailVerified && (
|
|
<Badge variant="orange" size="sm" className="ml-2" data-testid={`${dataTestId}-unverified-badge`}>
|
|
{t("unverified")}
|
|
</Badge>
|
|
)}
|
|
<Dropdown>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button
|
|
StartIcon="ellipsis"
|
|
variant="icon"
|
|
size="sm"
|
|
color="secondary"
|
|
className="ml-2 rounded-md"
|
|
data-testid="secondary-email-action-group-button"
|
|
/>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent>
|
|
<DropdownMenuItem>
|
|
<DropdownItem
|
|
StartIcon="flag"
|
|
color="secondary"
|
|
className="disabled:opacity-40"
|
|
onClick={handleChangePrimary}
|
|
disabled={!emailVerified || emailPrimary}
|
|
data-testid="secondary-email-make-primary-button">
|
|
{t("make_primary")}
|
|
</DropdownItem>
|
|
</DropdownMenuItem>
|
|
{!emailVerified && (
|
|
<DropdownMenuItem>
|
|
<DropdownItem
|
|
StartIcon="send"
|
|
color="secondary"
|
|
className="disabled:opacity-40"
|
|
onClick={handleVerifyEmail}
|
|
disabled={emailVerified}
|
|
data-testid="resend-verify-email-button">
|
|
{t("resend_email")}
|
|
</DropdownItem>
|
|
</DropdownMenuItem>
|
|
)}
|
|
<DropdownMenuItem>
|
|
<DropdownItem
|
|
StartIcon="trash"
|
|
color="destructive"
|
|
className="disabled:opacity-40"
|
|
onClick={handleItemDelete}
|
|
disabled={emailPrimary}
|
|
data-testid="secondary-email-delete-button">
|
|
{t("delete")}
|
|
</DropdownItem>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</Dropdown>
|
|
</div>
|
|
</div>
|
|
{errorMessage && <InputError message={errorMessage} />}
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default CustomEmailTextField;
|