Skip to content

refactor: redesign Paywall component #11907

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions site/src/components/Paywall/Paywall.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Meta, StoryObj } from "@storybook/react";
import { Paywall } from "./Paywall";

const meta: Meta<typeof Paywall> = {
title: "components/Paywall",
component: Paywall,
};

export default meta;
type Story = StoryObj<typeof Paywall>;

const Example: Story = {
args: {
message: "Black Lotus",
description:
"Adds 3 mana of any single color of your choice to your mana pool, then is discarded. Tapping this artifact can be played as an interrupt.",
},
};

export { Example as Paywall };
96 changes: 83 additions & 13 deletions site/src/components/Paywall/Paywall.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,95 @@
import { type FC, type ReactNode } from "react";
import { type Interpolation, type Theme } from "@emotion/react";
import Button from "@mui/material/Button";
import Link from "@mui/material/Link";
import TaskAltIcon from "@mui/icons-material/TaskAlt";
import { type FC, type ReactNode } from "react";
import { EnterpriseBadge } from "components/Badges/Badges";
import { Stack } from "components/Stack/Stack";
import { docs } from "utils/docs";

export interface PaywallProps {
children?: ReactNode;
message: string;
description?: string | ReactNode;
cta?: ReactNode;
description?: ReactNode;
documentationLink?: string;
}

export const Paywall: FC<PaywallProps> = ({ message, description, cta }) => {
export const Paywall: FC<PaywallProps> = ({
message,
description,
documentationLink,
}) => {
return (
<div css={styles.root}>
<div css={{ marginBottom: 24 }}>
<Stack direction="row" alignItems="center" justifyContent="center">
<div>
<Stack direction="row" alignItems="center" css={{ marginBottom: 24 }}>
<h5 css={styles.title}>{message}</h5>
<EnterpriseBadge />
</Stack>

{description && <p css={styles.description}>{description}</p>}
<Link
href={documentationLink}
target="_blank"
rel="noreferrer"
css={{ fontWeight: 600 }}
>
Read the documentation
</Link>
</div>
{cta}
<div css={styles.separator}></div>
<Stack direction="column" alignItems="center" spacing={3}>
<ul css={styles.featureList}>
<li css={styles.feature}>
<FeatureIcon /> Template access control
</li>
<li css={styles.feature}>
<FeatureIcon /> User groups
</li>
<li css={styles.feature}>
<FeatureIcon /> 24 hour support
</li>
<li css={styles.feature}>
<FeatureIcon /> Audit logs
</li>
</ul>
<Button
href={docs("/enterprise")}
target="_blank"
rel="noreferrer"
startIcon={<span css={{ fontSize: 22 }}>&rarr;</span>}
variant="outlined"
color="neutral"
>
Learn about Enterprise
</Button>
</Stack>
</div>
);
};

const FeatureIcon: FC = () => {
return <TaskAltIcon css={styles.featureIcon} />;
};

const styles = {
root: (theme) => ({
display: "flex",
flexDirection: "column",
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
textAlign: "center",
minHeight: 300,
maxWidth: 920,
margin: "auto",
padding: 24,
backgroundColor: theme.palette.background.paper,
border: `1px solid ${theme.palette.divider}`,
backgroundImage: `linear-gradient(160deg, transparent, ${theme.experimental.roles.active.background})`,
border: `1px solid ${theme.experimental.roles.active.fill.outline}`,
borderRadius: 8,
gap: 32,
}),
title: {
fontWeight: 600,
fontFamily: "inherit",
fontSize: 24,
fontSize: 22,
margin: 0,
},
description: (theme) => ({
Expand All @@ -51,6 +98,29 @@ const styles = {
maxWidth: 420,
lineHeight: "160%",
color: theme.palette.text.secondary,
fontSize: 16,
}),
separator: (theme) => ({
width: 1,
height: 220,
backgroundColor: theme.palette.divider,
marginLeft: 8,
}),
featureList: {
listStyle: "none",
margin: 0,
marginRight: 8,
padding: "0 12px",
fontSize: 14,
fontWeight: 500,
},
featureIcon: (theme) => ({
color: theme.experimental.roles.active.fill.outline,
}),
feature: {
display: "flex",
alignItems: "center",
padding: 3,
gap: 8,
},
} satisfies Record<string, Interpolation<Theme>>;
20 changes: 12 additions & 8 deletions site/src/pages/AuditPage/AuditPageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableRow from "@mui/material/TableRow";
import { AuditLog } from "api/typesGenerated";
import { AuditLogRow } from "./AuditLogRow/AuditLogRow";
import { type ComponentProps, type FC } from "react";
import type { AuditLog } from "api/typesGenerated";
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
import { EmptyState } from "components/EmptyState/EmptyState";
import { Margins } from "components/Margins/Margins";
Expand All @@ -16,15 +16,15 @@ import {
import { Stack } from "components/Stack/Stack";
import { TableLoader } from "components/TableLoader/TableLoader";
import { Timeline } from "components/Timeline/Timeline";
import { AuditHelpTooltip } from "./AuditHelpTooltip";
import { ComponentProps, FC } from "react";
import { AuditPaywall } from "./AuditPaywall";
import { AuditFilter } from "./AuditFilter";

import { Paywall } from "components/Paywall/Paywall";
import {
type PaginationResult,
PaginationContainer,
} from "components/PaginationWidget/PaginationContainer";
import { docs } from "utils/docs";
import { AuditHelpTooltip } from "./AuditHelpTooltip";
import { AuditFilter } from "./AuditFilter";
import { AuditLogRow } from "./AuditLogRow/AuditLogRow";

export const Language = {
title: "Audit",
Expand Down Expand Up @@ -130,7 +130,11 @@ export const AuditPageView: FC<AuditPageViewProps> = ({
</Cond>

<Cond>
<AuditPaywall />
<Paywall
message="Audit logs"
description="Audit logs allow you to monitor user operations on your deployment. You need an Enterprise license to use this feature."
documentationLink={docs("/admin/audit-logs")}
/>
</Cond>
</ChooseOne>
</Margins>
Expand Down
36 changes: 0 additions & 36 deletions site/src/pages/AuditPage/AuditPaywall.tsx

This file was deleted.

28 changes: 2 additions & 26 deletions site/src/pages/GroupsPage/GroupsPageView.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import { type Interpolation, type Theme } from "@emotion/react";
import Button from "@mui/material/Button";
import Link from "@mui/material/Link";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import ArrowRightAltOutlined from "@mui/icons-material/ArrowRightAltOutlined";
import Skeleton from "@mui/material/Skeleton";
import AddOutlined from "@mui/icons-material/AddOutlined";
import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight";
import AvatarGroup from "@mui/material/AvatarGroup";
import { AvatarData } from "components/AvatarData/AvatarData";
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
import { EmptyState } from "components/EmptyState/EmptyState";
import { Stack } from "components/Stack/Stack";
import {
TableLoaderSkeleton,
TableRowSkeleton,
Expand All @@ -26,7 +24,6 @@ import { Paywall } from "components/Paywall/Paywall";
import type { Group } from "api/typesGenerated";
import { GroupAvatar } from "components/GroupAvatar/GroupAvatar";
import { docs } from "utils/docs";
import Skeleton from "@mui/material/Skeleton";
import { AvatarDataSkeleton } from "components/AvatarData/AvatarDataSkeleton";

export type GroupsPageViewProps = {
Expand All @@ -51,28 +48,7 @@ export const GroupsPageView: FC<GroupsPageViewProps> = ({
<Paywall
message="Groups"
description="Organize users into groups with restricted access to templates. You need an Enterprise license to use this feature."
cta={
<Stack direction="row" alignItems="center">
<Button
href={docs("/enterprise")}
target="_blank"
rel="noreferrer"
startIcon={<ArrowRightAltOutlined />}
variant="contained"
color="primary"
>
Learn about Enterprise
</Button>

<Link
href={docs("/admin/groups")}
target="_blank"
rel="noreferrer"
>
Read the documentation
</Link>
</Stack>
}
documentationLink={docs("/admin/groups")}
/>
</Cond>
<Cond>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import Button from "@mui/material/Button";
import Link from "@mui/material/Link";
import ArrowRightAltOutlined from "@mui/icons-material/ArrowRightAltOutlined";
import { type FC } from "react";
import { Helmet } from "react-helmet-async";
import { useMutation, useQuery, useQueryClient } from "react-query";
import { setGroupRole, setUserRole, templateACL } from "api/queries/templates";
import { Paywall } from "components/Paywall/Paywall";
import { Stack } from "components/Stack/Stack";
import { displaySuccess } from "components/GlobalSnackbar/utils";
import { useOrganizationId } from "contexts/auth/useOrganizationId";
import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility";
Expand Down Expand Up @@ -38,26 +34,8 @@ export const TemplatePermissionsPage: FC = () => {
{!isTemplateRBACEnabled ? (
<Paywall
message="Template permissions"
description="Manage your template permissions to allow users or groups to view or admin the template. To use this feature, you have to upgrade your account."
cta={
<Stack direction="row" alignItems="center">
<Link
href={docs("/admin/upgrade")}
target="_blank"
rel="noreferrer"
>
<Button
startIcon={<ArrowRightAltOutlined />}
variant="contained"
>
See how to upgrade
</Button>
</Link>
<Link href={docs("/admin/rbac")} target="_blank" rel="noreferrer">
Read the documentation
</Link>
</Stack>
}
description="Control access of templates for users and groups to templates. You need an Enterprise license to use this feature."
documentationLink={docs("/admin/rbac")}
/>
) : (
<TemplatePermissionsPageView
Expand Down
2 changes: 1 addition & 1 deletion site/src/theme/dark/experimental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export default {
text: colors.sky[50],
fill: {
solid: colors.sky[600],
outline: colors.sky[600],
outline: colors.sky[400],
text: colors.white,
},
disabled: {
Expand Down