diff --git a/site/src/components/Paywall/Paywall.stories.tsx b/site/src/components/Paywall/Paywall.stories.tsx new file mode 100644 index 0000000000..d7917231df --- /dev/null +++ b/site/src/components/Paywall/Paywall.stories.tsx @@ -0,0 +1,20 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { Paywall } from "./Paywall"; + +const meta: Meta = { + title: "components/Paywall", + component: Paywall, +}; + +export default meta; +type Story = StoryObj; + +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 }; diff --git a/site/src/components/Paywall/Paywall.tsx b/site/src/components/Paywall/Paywall.tsx index b24acfff07..5e073c438a 100644 --- a/site/src/components/Paywall/Paywall.tsx +++ b/site/src/components/Paywall/Paywall.tsx @@ -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 = ({ message, description, cta }) => { +export const Paywall: FC = ({ + message, + description, + documentationLink, +}) => { return (
-
- +
+
{message}
{description &&

{description}

} + + Read the documentation +
- {cta} +
+ +
    +
  • + Template access control +
  • +
  • + User groups +
  • +
  • + 24 hour support +
  • +
  • + Audit logs +
  • +
+ +
); }; +const FeatureIcon: FC = () => { + return ; +}; + 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) => ({ @@ -51,6 +98,29 @@ const styles = { maxWidth: 420, lineHeight: "160%", color: theme.palette.text.secondary, - fontSize: 14, + 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>; diff --git a/site/src/pages/AuditPage/AuditPageView.tsx b/site/src/pages/AuditPage/AuditPageView.tsx index 085cf14af1..84cabc9d36 100644 --- a/site/src/pages/AuditPage/AuditPageView.tsx +++ b/site/src/pages/AuditPage/AuditPageView.tsx @@ -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"; @@ -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", @@ -130,7 +130,11 @@ export const AuditPageView: FC = ({ - + diff --git a/site/src/pages/AuditPage/AuditPaywall.tsx b/site/src/pages/AuditPage/AuditPaywall.tsx deleted file mode 100644 index 8de74dbdc2..0000000000 --- a/site/src/pages/AuditPage/AuditPaywall.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import Button from "@mui/material/Button"; -import Link from "@mui/material/Link"; -import ArrowRightAltOutlined from "@mui/icons-material/ArrowRightAltOutlined"; -import { Paywall } from "components/Paywall/Paywall"; -import { Stack } from "components/Stack/Stack"; -import { FC } from "react"; -import { docs } from "utils/docs"; - -export const AuditPaywall: FC = () => { - return ( - - - - - - Read the documentation - - - } - /> - ); -}; diff --git a/site/src/pages/GroupsPage/GroupsPageView.tsx b/site/src/pages/GroupsPage/GroupsPageView.tsx index faaafafb9d..a71ffe1867 100644 --- a/site/src/pages/GroupsPage/GroupsPageView.tsx +++ b/site/src/pages/GroupsPage/GroupsPageView.tsx @@ -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, @@ -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 = { @@ -51,28 +48,7 @@ export const GroupsPageView: FC = ({ - - - - Read the documentation - - - } + documentationLink={docs("/admin/groups")} /> diff --git a/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPage.tsx b/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPage.tsx index f7173ff0d6..99b3f7efa7 100644 --- a/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPage.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPage.tsx @@ -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"; @@ -38,26 +34,8 @@ export const TemplatePermissionsPage: FC = () => { {!isTemplateRBACEnabled ? ( - - - - - Read the documentation - - - } + description="Control access of templates for users and groups to templates. You need an Enterprise license to use this feature." + documentationLink={docs("/admin/rbac")} /> ) : (