Skip to content

Commit

Permalink
feat(web): v3 dashboard opt-in widget (#6873)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChmaraX authored Nov 7, 2024
1 parent 5685a85 commit b427d72
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .source
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { Card } from '@mantine/core';
import { css } from '@novu/novui/css';
import { Text, Title, Button, IconButton } from '@novu/novui';
import { IconOutlineClose } from '@novu/novui/icons';
import { useUser } from '@clerk/clerk-react';
import { FeatureFlagsKeysEnum, NewDashboardOptInStatusEnum } from '@novu/shared';
import { IS_SELF_HOSTED } from '../../../../config';
import { useFeatureFlag } from '../../../../hooks';

export function NewDashboardOptInWidget() {
const { user } = useUser();
const isNewDashboardEnabled = useFeatureFlag(FeatureFlagsKeysEnum.IS_NEW_DASHBOARD_ENABLED);

const isDismissed = user?.unsafeMetadata?.newDashboardOptInStatus === NewDashboardOptInStatusEnum.DISMISSED;

if (IS_SELF_HOSTED || isDismissed || !isNewDashboardEnabled) {
return null;
}

const updateUserOptInStatus = (status: NewDashboardOptInStatusEnum) => {
if (!user) return;

user.update({
unsafeMetadata: {
...user.unsafeMetadata,
newDashboardOptInStatus: status,
},
});
};

function handleOptIn() {
const newDashboardUrl = process.env.NEW_DASHBOARD_URL;
if (!newDashboardUrl || !user) return;

updateUserOptInStatus(NewDashboardOptInStatusEnum.OPTED_IN);
window.location.href = newDashboardUrl;
}

function handleDismiss() {
updateUserOptInStatus(NewDashboardOptInStatusEnum.DISMISSED);
}

return (
<Card shadow="sm" className={styles.card}>
<div className={styles.content}>
<div className={styles.header}>
<Title className={styles.title}>
<span style={{ marginRight: '4px' }}>🎉</span> You're invited!
</Title>
<IconButton onClick={handleDismiss} Icon={IconOutlineClose} size="xs" />
</div>
<Text className={styles.text}>
We’d love to extend you the access for the new workflows dashboard that we’re building.
</Text>
</div>
<div className={styles.buttonContainer}>
<Button size="sm" variant="transparent" onClick={handleOptIn}>
Take me there
</Button>
</div>
</Card>
);
}

const styles = {
card: css({
padding: '9px 16px !important',
backgroundColor: 'surface.popover !important',
_before: {
content: '""',
position: 'absolute',
width: '50',
top: '0',
right: '0',
bottom: '0',
left: '0',
borderTopLeftRadius: '100',
borderBottomLeftRadius: '100',
bgGradient: `to-b`,
gradientFrom: 'colorPalette.start',
gradientTo: 'colorPalette.end',
},
}),
content: css({
display: 'flex',
flexDirection: 'column',
gap: '4px',
alignSelf: 'stretch',
}),
header: css({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
gap: '8px',
}),
title: css({
fontSize: '12px',
fontWeight: '700 ',
lineHeight: '20px',
}),
text: css({
fontSize: '12px',
lineHeight: '16px',
fontWeight: '500',
fontStyle: 'normal',
}),
buttonContainer: css({
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
}),
};
2 changes: 2 additions & 0 deletions apps/web/src/components/nav/RootNavMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { SidebarFooter } from '../layout/components/LocalStudioSidebar/SidebarFo
import { useNavigateToLocalStudio } from '../../studio/hooks/useNavigateToLocalStudio';
import { OpenLocalStudioModal } from '../../studio/components/OpenLocalStudioModal';
import { OutlineButton } from '../../studio/components/OutlineButton';
import { NewDashboardOptInWidget } from '../layout/components/v2/NewDashboardOptInWidget';

const getEnvPageRoute = (route: ROUTES, env: BaseEnvironmentEnum) => parseUrl(route, { env });

Expand Down Expand Up @@ -161,6 +162,7 @@ export const RootNavMenu: React.FC = () => {
{isV2Enabled ? (
<>
<SidebarFooter>
<NewDashboardOptInWidget />
<FreeTrialSidebarWidget />
<OutlineButton fullWidth onClick={navigateToLocalStudio} Icon={IconLaptop}>
Open Local Studio
Expand Down
14 changes: 14 additions & 0 deletions packages/shared/src/types/clerk/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,17 @@ export type UserPublicMetadata = {
servicesHashes?: IServicesHashes;
jobTitle?: JobTitleEnum;
};

/**
* Unsafe metadata can be updated from the frontend directly
*/
export type UserUnsafeMetadata = {
newDashboardOptInStatus?: NewDashboardOptInStatusEnum;
};

export enum NewDashboardOptInStatusEnum {
OPTED_IN = 'opted_in', // user switched to the new dashboard
DISMISSED = 'dismissed', // user dismissed the opt-in widget
OPTED_OUT = 'opted_out', // user switched back to the old dashboard
// undefined -> user has not interacted with the widget yet
}
1 change: 1 addition & 0 deletions packages/shared/src/types/feature-flags/feature-flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export enum FeatureFlagsKeysEnum {
IS_INTEGRATION_INVALIDATION_DISABLED = 'IS_INTEGRATION_INVALIDATION_DISABLED',
IS_EMAIL_INLINE_CSS_DISABLED = 'IS_EMAIL_INLINE_CSS_DISABLED',
IS_CONTROLS_AUTOCOMPLETE_ENABLED = 'IS_CONTROLS_AUTOCOMPLETE_ENABLED',
IS_NEW_DASHBOARD_ENABLED = 'IS_NEW_DASHBOARD_ENABLED',
}

0 comments on commit b427d72

Please sign in to comment.