Skip to content

Commit cc90a62

Browse files
authored
feat: add banner for upgrade when using company email (calcom#24829)
* Add banner plus mail icon * Update MailIcon.tsx * Update profile-view.tsx * Fix weird line
1 parent 79bcd6d commit cc90a62

4 files changed

Lines changed: 266 additions & 1 deletion

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"use client";
2+
3+
import { useRouter } from "next/navigation";
4+
5+
import { useFlagMap } from "@calcom/features/flags/context/provider";
6+
import { useLocale } from "@calcom/lib/hooks/useLocale";
7+
import { Button } from "@calcom/ui/components/button";
8+
9+
import { MailIcon } from "./MailIcon";
10+
11+
type CompanyEmailOrganizationBannerProps = {
12+
onDismissAction: () => void;
13+
};
14+
15+
export const CompanyEmailOrganizationBanner = ({ onDismissAction }: CompanyEmailOrganizationBannerProps) => {
16+
const { t } = useLocale();
17+
const router = useRouter();
18+
const flags = useFlagMap();
19+
20+
const handleLearnMore = () => {
21+
const redirectPath = flags["onboarding-v3"]
22+
? "/onboarding/organization/details"
23+
: "/settings/organizations/new";
24+
router.push(redirectPath);
25+
};
26+
27+
if (!flags["onboarding-v3"]) {
28+
return null;
29+
}
30+
31+
return (
32+
<div className="border-subtle from-muted relative mb-6 overflow-hidden rounded-lg border bg-gradient-to-r to-transparent p-4">
33+
{/* Dot grid background with fade */}
34+
<svg className="pointer-events-none absolute inset-0 h-full w-full" xmlns="http://www.w3.org/2000/svg">
35+
<defs>
36+
{/* Dot pattern - 12px spacing */}
37+
<pattern id="banner-dot-pattern" x="0" y="0" width="12" height="12" patternUnits="userSpaceOnUse">
38+
<circle cx="1" cy="1" r="0.8" fill="currentColor" className="text-subtle" opacity="0.3" />
39+
</pattern>
40+
{/* Fade mask from left to right */}
41+
<linearGradient id="banner-fade-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
42+
<stop offset="0%" stopColor="white" stopOpacity="1" />
43+
<stop offset="10%" stopColor="white" stopOpacity="0.4" />
44+
<stop offset="100%" stopColor="white" stopOpacity="0" />
45+
</linearGradient>
46+
<mask id="banner-fade-mask">
47+
<rect x="0" y="0" width="100%" height="100%" fill="url(#banner-fade-gradient)" />
48+
</mask>
49+
</defs>
50+
{/* Apply pattern with mask */}
51+
<rect
52+
x="0"
53+
y="0"
54+
width="100%"
55+
height="100%"
56+
fill="url(#banner-dot-pattern)"
57+
mask="url(#banner-fade-mask)"
58+
/>
59+
</svg>
60+
61+
<div className="relative z-10 flex gap-4">
62+
<div>
63+
<MailIcon />
64+
</div>
65+
<div className="flex flex-1 flex-col gap-2">
66+
<div className="flex flex-col">
67+
<h3 className="text-default text-sm font-semibold">
68+
{t("it_appears_you_are_using_company_email")}
69+
</h3>
70+
<p className="text-default text-sm">{t("explore_organizational_plan_description")}</p>
71+
</div>
72+
<div className="mt-2 flex gap-2">
73+
<Button color="secondary" onClick={onDismissAction}>
74+
{t("dismiss")}
75+
</Button>
76+
<Button color="primary" EndIcon="external-link" onClick={handleLearnMore}>
77+
{t("upgrade")}
78+
</Button>
79+
</div>
80+
</div>
81+
</div>
82+
</div>
83+
);
84+
};
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
export function MailIcon() {
2+
return (
3+
<svg width="124" height="110" viewBox="0 0 124 110" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
4+
<style>
5+
{`:root {
6+
--mail-envelope-start: white;
7+
--mail-envelope-end: #F7F7F7;
8+
--mail-border-start: #E5E5E6;
9+
--mail-border-end: #B2B2B2;
10+
--mail-badge-start: #F7F7F7;
11+
--mail-badge-end: #D3D3D3;
12+
--mail-badge-stroke: #E8E8E8;
13+
--mail-badge-text: #6B7280;
14+
--mail-circle-start: white;
15+
--mail-circle-end: #EEEEEE;
16+
--mail-circle-border-start: #E8E8E8;
17+
--mail-circle-border-end: #B2B2B2;
18+
--mail-at-start: #6B7280;
19+
--mail-at-end: #3C3F43;
20+
}
21+
.dark {
22+
--mail-envelope-start: #1c1917;
23+
--mail-envelope-end: #292524;
24+
--mail-border-start: #44403c;
25+
--mail-border-end: #57534e;
26+
--mail-badge-start: #292524;
27+
--mail-badge-end: #1c1917;
28+
--mail-badge-stroke: #44403c;
29+
--mail-badge-text: #a8a29e;
30+
--mail-circle-start: #292524;
31+
--mail-circle-end: #1c1917;
32+
--mail-circle-border-start: #44403c;
33+
--mail-circle-border-end: #57534e;
34+
--mail-at-start: #a8a29e;
35+
--mail-at-end: #78716c;
36+
}`}
37+
</style>
38+
<g>
39+
<g>
40+
<path
41+
d="M17.3 18H91.7C96.815 18 101 22.1625 101 27.25V82.75C101 87.8375 96.815 92 91.7 92H17.3C12.185 92 8 87.8375 8 82.75V27.25C8 22.1625 12.185 18 17.3 18Z"
42+
fill="url(#paint0_linear_3039_74057)"
43+
/>
44+
<path
45+
d="M101 27.25L59.0711 56.4424C56.3238 58.3552 52.6762 58.3552 49.9289 56.4424L8 27.25"
46+
fill="url(#paint0_linear_3039_74057)"
47+
/>
48+
<path
49+
d="M101 27.25C101 22.1625 96.815 18 91.7 18H17.3C12.185 18 8 22.1625 8 27.25M101 27.25V82.75C101 87.8375 96.815 92 91.7 92H17.3C12.185 92 8 87.8375 8 82.75V27.25M101 27.25L59.0711 56.4424C56.3238 58.3552 52.6762 58.3552 49.9289 56.4424L8 27.25"
50+
stroke="url(#paint2_linear_3039_74057)"
51+
strokeWidth="1.63366"
52+
strokeLinecap="round"
53+
strokeLinejoin="round"
54+
/>
55+
</g>
56+
<g opacity="0.6">
57+
<path
58+
d="M11 83C11 79.6863 13.6863 77 17 77H29C32.3137 77 35 79.6863 35 83C35 86.3137 32.3137 89 29 89H17C13.6863 89 11 86.3137 11 83Z"
59+
fill="url(#paint3_linear_3039_74057)"
60+
/>
61+
<path
62+
d="M17 77.25H29C32.1756 77.25 34.75 79.8244 34.75 83C34.75 86.1756 32.1756 88.75 29 88.75H17C13.8244 88.75 11.25 86.1756 11.25 83C11.25 79.8244 13.8244 77.25 17 77.25Z"
63+
stroke="var(--mail-badge-stroke)"
64+
strokeWidth="0.5"
65+
/>
66+
<path
67+
d="M16.3807 85.0724C16.1733 85.0724 15.9858 85.0341 15.8182 84.9574C15.6506 84.8793 15.5178 84.7663 15.4197 84.6186C15.3232 84.4709 15.2749 84.2898 15.2749 84.0753C15.2749 83.8906 15.3104 83.7386 15.3814 83.6193C15.4524 83.5 15.5483 83.4055 15.669 83.3359C15.7898 83.2663 15.9247 83.2138 16.0739 83.1783C16.223 83.1428 16.375 83.1158 16.5298 83.0973C16.7259 83.0746 16.8849 83.0561 17.0071 83.0419C17.1293 83.0263 17.218 83.0014 17.2734 82.9673C17.3288 82.9332 17.3565 82.8778 17.3565 82.8011V82.7862C17.3565 82.6001 17.304 82.456 17.1989 82.3537C17.0952 82.2514 16.9403 82.2003 16.7344 82.2003C16.5199 82.2003 16.3509 82.2479 16.2273 82.343C16.1051 82.4368 16.0206 82.5412 15.9737 82.6562L15.375 82.5199C15.446 82.321 15.5497 82.1605 15.6861 82.0384C15.8239 81.9148 15.9822 81.8253 16.1612 81.7699C16.3402 81.7131 16.5284 81.6847 16.7259 81.6847C16.8565 81.6847 16.995 81.7003 17.1413 81.7315C17.2891 81.7614 17.4268 81.8168 17.5547 81.8977C17.6839 81.9787 17.7898 82.0945 17.8722 82.245C17.9545 82.3942 17.9957 82.5881 17.9957 82.8267V85H17.3736V84.5526H17.348C17.3068 84.6349 17.245 84.7159 17.1626 84.7955C17.0803 84.875 16.9744 84.9411 16.8452 84.9936C16.7159 85.0462 16.5611 85.0724 16.3807 85.0724ZM16.5192 84.5611C16.6953 84.5611 16.8459 84.5263 16.9709 84.4567C17.0973 84.3871 17.1932 84.2962 17.2585 84.1839C17.3253 84.0703 17.3587 83.9489 17.3587 83.8196V83.3977C17.3359 83.4205 17.2919 83.4418 17.2266 83.4616C17.1626 83.4801 17.0895 83.4964 17.0071 83.5107C16.9247 83.5234 16.8445 83.5355 16.7663 83.5469C16.6882 83.5568 16.6229 83.5653 16.5703 83.5724C16.4467 83.5881 16.3338 83.6143 16.2315 83.6513C16.1307 83.6882 16.0497 83.7415 15.9886 83.8111C15.929 83.8793 15.8991 83.9702 15.8991 84.0838C15.8991 84.2415 15.9574 84.3608 16.0739 84.4418C16.1903 84.5213 16.3388 84.5611 16.5192 84.5611ZM20.2228 85.0661C19.9061 85.0661 19.6333 84.9943 19.4047 84.8509C19.1774 84.706 19.0027 84.5064 18.8805 84.2521C18.7583 83.9979 18.6973 83.7067 18.6973 83.3786C18.6973 83.0462 18.7598 82.7528 18.8848 82.4986C19.0098 82.2429 19.1859 82.0433 19.4132 81.8999C19.6404 81.7564 19.9082 81.6847 20.2164 81.6847C20.465 81.6847 20.6866 81.7308 20.8812 81.8232C21.0758 81.9141 21.2328 82.0419 21.3521 82.2067C21.4728 82.3714 21.5446 82.5639 21.5673 82.7841H20.9473C20.9132 82.6307 20.835 82.4986 20.7129 82.3878C20.5922 82.277 20.4302 82.2216 20.2271 82.2216C20.0495 82.2216 19.894 82.2685 19.7605 82.3622C19.6284 82.4545 19.5254 82.5866 19.4515 82.7585C19.3777 82.929 19.3407 83.1307 19.3407 83.3636C19.3407 83.6023 19.377 83.8082 19.4494 83.9815C19.5218 84.1548 19.6241 84.2891 19.7562 84.3842C19.8897 84.4794 20.0467 84.527 20.2271 84.527C20.3478 84.527 20.4572 84.505 20.5552 84.4609C20.6547 84.4155 20.7377 84.3509 20.8045 84.267C20.8727 84.1832 20.9203 84.0824 20.9473 83.9645H21.5673C21.5446 84.1761 21.4757 84.3651 21.3606 84.5312C21.2456 84.6974 21.0914 84.8281 20.8983 84.9233C20.7065 85.0185 20.4814 85.0661 20.2228 85.0661ZM22.2486 85V81.7273H22.8601V82.2599H22.9006C22.9688 82.0795 23.0803 81.9389 23.2351 81.8381C23.3899 81.7358 23.5753 81.6847 23.7912 81.6847C24.0099 81.6847 24.1932 81.7358 24.3409 81.8381C24.4901 81.9403 24.6001 82.081 24.6712 82.2599H24.7053C24.7834 82.0852 24.9077 81.946 25.0781 81.8423C25.2486 81.7372 25.4517 81.6847 25.6875 81.6847C25.9844 81.6847 26.2266 81.7777 26.4141 81.9638C26.603 82.1499 26.6974 82.4304 26.6974 82.8054V85H26.0604V82.8651C26.0604 82.6435 26 82.483 25.8793 82.3835C25.7585 82.2841 25.6143 82.2344 25.4467 82.2344C25.2393 82.2344 25.0781 82.2983 24.9631 82.4261C24.848 82.5526 24.7905 82.7152 24.7905 82.9141V85H24.1555V82.8246C24.1555 82.647 24.1001 82.5043 23.9893 82.3963C23.8786 82.2884 23.7344 82.2344 23.5568 82.2344C23.4361 82.2344 23.3246 82.2663 23.2223 82.3303C23.1214 82.3928 23.0398 82.4801 22.9773 82.5923C22.9162 82.7045 22.8857 82.8345 22.8857 82.9822V85H22.2486ZM28.9618 85.0661C28.6394 85.0661 28.3617 84.9972 28.1287 84.8594C27.8972 84.7202 27.7182 84.5249 27.5918 84.2734C27.4668 84.0206 27.4043 83.7244 27.4043 83.3849C27.4043 83.0497 27.4668 82.7543 27.5918 82.4986C27.7182 82.2429 27.8944 82.0433 28.1202 81.8999C28.3475 81.7564 28.6131 81.6847 28.9171 81.6847C29.1017 81.6847 29.2807 81.7152 29.454 81.7763C29.6273 81.8374 29.7828 81.9332 29.9206 82.0639C30.0584 82.1946 30.1671 82.3643 30.2466 82.5732C30.3262 82.7805 30.3659 83.0327 30.3659 83.3295V83.5554H27.7644V83.0781H29.7417C29.7417 82.9105 29.7076 82.7621 29.6394 82.6328C29.5712 82.5021 29.4753 82.3991 29.3517 82.3239C29.2296 82.2486 29.0861 82.2109 28.9213 82.2109C28.7424 82.2109 28.5861 82.255 28.4526 82.343C28.3205 82.4297 28.2182 82.5433 28.1458 82.6839C28.0748 82.8232 28.0392 82.9744 28.0392 83.1378V83.5107C28.0392 83.7294 28.0776 83.9155 28.1543 84.0689C28.2324 84.2223 28.3411 84.3395 28.4803 84.4205C28.6195 84.5 28.7821 84.5398 28.9682 84.5398C29.089 84.5398 29.199 84.5227 29.2985 84.4886C29.3979 84.4531 29.4838 84.4006 29.5563 84.331C29.6287 84.2614 29.6841 84.1754 29.7225 84.0732L30.3255 84.1818C30.2772 84.3594 30.1905 84.5149 30.0655 84.6484C29.9419 84.7805 29.7864 84.8835 29.5989 84.9574C29.4128 85.0298 29.2005 85.0661 28.9618 85.0661Z"
68+
fill="var(--mail-badge-text)"
69+
/>
70+
</g>
71+
</g>
72+
<g>
73+
<path
74+
d="M84 23C84 13.0589 92.0589 5 102 5C111.941 5 120 13.0589 120 23C120 32.9411 111.941 41 102 41C92.0589 41 84 32.9411 84 23Z"
75+
fill="white"
76+
/>
77+
<path
78+
d="M84 23C84 13.0589 92.0589 5 102 5C111.941 5 120 13.0589 120 23C120 32.9411 111.941 41 102 41C92.0589 41 84 32.9411 84 23Z"
79+
fill="url(#paint4_linear_3039_74057)"
80+
/>
81+
<path
82+
d="M102 5.81641C111.49 5.81641 119.184 13.51 119.184 23C119.184 32.49 111.49 40.1836 102 40.1836C92.51 40.1836 84.8164 32.49 84.8164 23C84.8164 13.51 92.51 5.81641 102 5.81641Z"
83+
stroke="url(#paint5_linear_3039_74057)"
84+
strokeWidth="1.63366"
85+
/>
86+
<g opacity="0.6">
87+
<path
88+
d="M105.63 19.3697V23.9076C105.63 24.6297 105.917 25.3223 106.428 25.8329C106.938 26.3435 107.631 26.6304 108.353 26.6304C109.075 26.6304 109.768 26.3435 110.278 25.8329C110.789 25.3223 111.076 24.6297 111.076 23.9076V23C111.076 20.9516 110.383 18.9635 109.109 17.3589C107.836 15.7544 106.057 14.6277 104.063 14.1622C102.068 13.6966 99.9742 13.9196 98.1222 14.7948C96.2702 15.67 94.7687 17.146 93.8619 18.9828C92.955 20.8195 92.6962 22.909 93.1275 24.9115C93.5588 26.914 94.6548 28.7117 96.2374 30.0123C97.8199 31.3129 99.7958 32.0399 101.844 32.0752C103.892 32.1104 105.892 31.4517 107.518 30.2063M105.63 23C105.63 25.005 104.005 26.6304 102 26.6304C99.995 26.6304 98.3696 25.005 98.3696 23C98.3696 20.995 99.995 19.3697 102 19.3697C104.005 19.3697 105.63 20.995 105.63 23Z"
89+
stroke="url(#paint6_linear_3039_74057)"
90+
strokeWidth="1.63366"
91+
strokeLinecap="round"
92+
strokeLinejoin="round"
93+
/>
94+
</g>
95+
</g>
96+
<defs>
97+
<linearGradient
98+
id="paint0_linear_3039_74057"
99+
x1="54.5"
100+
y1="18"
101+
x2="54.5"
102+
y2="92"
103+
gradientUnits="userSpaceOnUse">
104+
<stop stopColor="var(--mail-envelope-start)" />
105+
<stop offset="1" stopColor="var(--mail-envelope-end)" />
106+
</linearGradient>
107+
<linearGradient
108+
id="paint2_linear_3039_74057"
109+
x1="54.5"
110+
y1="18"
111+
x2="54.5"
112+
y2="92"
113+
gradientUnits="userSpaceOnUse">
114+
<stop offset="0.195" stopColor="var(--mail-border-start)" />
115+
<stop offset="1" stopColor="var(--mail-border-end)" />
116+
</linearGradient>
117+
<linearGradient
118+
id="paint3_linear_3039_74057"
119+
x1="23"
120+
y1="77"
121+
x2="23"
122+
y2="89"
123+
gradientUnits="userSpaceOnUse">
124+
<stop stopColor="var(--mail-badge-start)" />
125+
<stop offset="1" stopColor="var(--mail-badge-end)" />
126+
</linearGradient>
127+
<linearGradient
128+
id="paint4_linear_3039_74057"
129+
x1="102"
130+
y1="5"
131+
x2="102"
132+
y2="41"
133+
gradientUnits="userSpaceOnUse">
134+
<stop offset="0.592418" stopColor="var(--mail-circle-start)" />
135+
<stop offset="1" stopColor="var(--mail-circle-end)" />
136+
</linearGradient>
137+
<linearGradient
138+
id="paint5_linear_3039_74057"
139+
x1="102"
140+
y1="5"
141+
x2="102"
142+
y2="41"
143+
gradientUnits="userSpaceOnUse">
144+
<stop stopColor="var(--mail-circle-border-start)" />
145+
<stop offset="1" stopColor="var(--mail-circle-border-end)" />
146+
</linearGradient>
147+
<linearGradient
148+
id="paint6_linear_3039_74057"
149+
x1="102"
150+
y1="13.9247"
151+
x2="102"
152+
y2="32.0765"
153+
gradientUnits="userSpaceOnUse">
154+
<stop stopColor="var(--mail-at-start)" />
155+
<stop offset="1" stopColor="var(--mail-at-end)" />
156+
</linearGradient>
157+
</defs>
158+
</svg>
159+
);
160+
}

apps/web/modules/settings/my-account/profile-view.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { z } from "zod";
1212

1313
import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode";
1414
import { Dialog } from "@calcom/features/components/controlled-dialog";
15+
import { isCompanyEmail } from "@calcom/features/ee/organizations/lib/utils";
1516
import SectionBottomActions from "@calcom/features/settings/SectionBottomActions";
1617
import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader";
1718
import { DisplayInfo } from "@calcom/features/users/components/UserTable/EditSheet/DisplayInfo";
@@ -46,6 +47,8 @@ import { UsernameAvailabilityField } from "@components/ui/UsernameAvailability";
4647

4748
import type { TRPCClientErrorLike } from "@trpc/client";
4849

50+
import { CompanyEmailOrganizationBanner } from "./components/CompanyEmailOrganizationBanner";
51+
4952
interface DeleteAccountValues {
5053
totpCode: string;
5154
}
@@ -72,7 +75,8 @@ type Props = {
7275
const ProfileView = ({ user }: Props) => {
7376
const { t } = useLocale();
7477
const utils = trpc.useUtils();
75-
const { update } = useSession();
78+
const session = useSession();
79+
const { update } = session;
7680
const updateProfileMutation = trpc.viewer.me.updateProfile.useMutation({
7781
onSuccess: async (res) => {
7882
await update(res);
@@ -138,6 +142,7 @@ const ProfileView = ({ user }: Props) => {
138142
const [deleteAccountOpen, setDeleteAccountOpen] = useState(false);
139143
const [hasDeleteErrors, setHasDeleteErrors] = useState(false);
140144
const [deleteErrorMessage, setDeleteErrorMessage] = useState("");
145+
const [isCompanyEmailAlertDismissed, setIsCompanyEmailAlertDismissed] = useState(false);
141146
const form = useForm<DeleteAccountValues>();
142147

143148
const onDeleteMeSuccessMutation = async () => {
@@ -250,6 +255,14 @@ const ProfileView = ({ user }: Props) => {
250255
],
251256
};
252257

258+
// Check if user should see company email alert
259+
const shouldShowCompanyEmailAlert =
260+
!isCompanyEmailAlertDismissed &&
261+
!session.data?.user?.org?.id &&
262+
!user.organization?.id &&
263+
userEmail &&
264+
isCompanyEmail(userEmail);
265+
253266
return (
254267
<SettingsHeader
255268
title={t("profile")}
@@ -301,6 +314,12 @@ const ProfileView = ({ user }: Props) => {
301314
isCALIdentityProvider={isCALIdentityProvider}
302315
/>
303316

317+
{shouldShowCompanyEmailAlert && (
318+
<div className="mt-6">
319+
<CompanyEmailOrganizationBanner onDismissAction={() => setIsCompanyEmailAlertDismissed(true)} />
320+
</div>
321+
)}
322+
304323
<div className="border-subtle mt-6 rounded-lg rounded-b-none border border-b-0 p-6">
305324
<Label className="mb-0 text-base font-semibold text-red-700">{t("danger_zone")}</Label>
306325
<p className="text-subtle text-sm">{t("account_deletion_cannot_be_undone")}</p>

apps/web/public/static/locales/en/common.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,8 @@
16921692
"profile_picture": "Profile Picture",
16931693
"upload": "Upload",
16941694
"add_profile_photo": "Add profile photo",
1695+
"it_appears_you_are_using_company_email": "It appears that you are utilizing your company email.",
1696+
"explore_organizational_plan_description": "Explore our new organizational plan! It boosts collaboration across event types and directs lost customers to the right team member.",
16951697
"token_address": "Token Address",
16961698
"blockchain": "Blockchain",
16971699
"old_password": "Old password",

0 commit comments

Comments
 (0)