diff --git a/packages/design-system/molecules/role-search/RoleSearch.tsx b/packages/design-system/molecules/role-search/RoleSearch.tsx index a5a714e..271a9e0 100644 --- a/packages/design-system/molecules/role-search/RoleSearch.tsx +++ b/packages/design-system/molecules/role-search/RoleSearch.tsx @@ -1,6 +1,7 @@ import { Role } from '@roleypoly/design-system/atoms/role'; import { Space } from '@roleypoly/design-system/atoms/space'; import { TextInputWithIcon } from '@roleypoly/design-system/atoms/text-input'; +import { Link } from '@roleypoly/design-system/atoms/typography'; import { Role as RoleType } from '@roleypoly/types'; import Fuse from 'fuse.js'; import * as React from 'react'; @@ -32,21 +33,36 @@ export const RoleSearch = (props: Props) => {
} - placeholder={props.placeholder || 'Search or drag a role...'} + placeholder={props.placeholder || 'Search for a role...'} value={props.searchTerm} onChange={(x) => props.onSearchUpdate(x.target.value)} /> - {results.map((resultRole, idx) => ( - - - - ))} + {props.roles.length > 0 ? ( + results.length > 0 ? ( + results.map((resultRole, idx) => ( + + + + )) + ) : ( + + No roles could be found. Try a different search term. +
+
+ ) + ) : ( + + Roleypoly can't see any more roles. +
+ Learn why +
+ )}
); }; diff --git a/packages/design-system/organisms/help-why-no-roles/WhyNoRoles.styled.ts b/packages/design-system/organisms/help-why-no-roles/WhyNoRoles.styled.ts index f3a2914..6b1ba73 100644 --- a/packages/design-system/organisms/help-why-no-roles/WhyNoRoles.styled.ts +++ b/packages/design-system/organisms/help-why-no-roles/WhyNoRoles.styled.ts @@ -1,6 +1,8 @@ import { numberToChroma, palette } from '@roleypoly/design-system/atoms/colors'; import { Role } from '@roleypoly/types'; -import styled, { css } from 'styled-components'; +import chroma from 'chroma-js'; +import { GoCheck, GoQuestion, GoX } from 'react-icons/go'; +import styled, { css, keyframes } from 'styled-components'; export const DiscordBase = styled.div` background-color: ${palette.discord100}; @@ -17,9 +19,26 @@ const hover = (roleColor: string) => css` cursor: pointer; `; +const isBadFlash = keyframes` + /* stylelint-disable function-name-case, function-whitespace-after */ + + 0%, 100% { + box-shadow: 0 0 8px ${chroma(palette.red400).alpha(0.5).css()} + } + + 66% { + box-shadow: 0 0 2px ${chroma(palette.red200).alpha(0.5).css()} + } + + 33% { + box-shadow: 0 0 2px ${chroma(palette.red400).alpha(0.5).css()} + } +`; + export const DiscordRole = styled.div<{ discordRole: Role; isRoleypoly: boolean; + isGood: boolean; }>` /* stylelint-disable function-name-case, function-whitespace-after */ @@ -35,4 +54,29 @@ export const DiscordRole = styled.div<{ ${(props) => props.isRoleypoly && hover(numberToChroma(props.discordRole.color).alpha(0.5).css())} + ${(props) => + !props.isGood && + props.isRoleypoly && + css` + animation: ${isBadFlash} 0.5s 10s ease-in-out both; + `} +`; + +const bumpDown = css` + position: relative; + top: 0.1em; + margin-right: 0.25em; +`; + +export const Dont = styled(GoX)` + ${bumpDown} + color: ${palette.red400}; +`; +export const Do = styled(GoCheck)` + ${bumpDown} + color: ${palette.green400}; +`; +export const Why = styled(GoQuestion)` + ${bumpDown} + color: ${palette.discord400}; `; diff --git a/packages/design-system/organisms/help-why-no-roles/WhyNoRoles.tsx b/packages/design-system/organisms/help-why-no-roles/WhyNoRoles.tsx index b4e1078..ab4d14f 100644 --- a/packages/design-system/organisms/help-why-no-roles/WhyNoRoles.tsx +++ b/packages/design-system/organisms/help-why-no-roles/WhyNoRoles.tsx @@ -1,12 +1,17 @@ import { palette } from '@roleypoly/design-system/atoms/colors'; import { HalfsiesContainer, HalfsiesItem } from '@roleypoly/design-system/atoms/halfsies'; import { SparkleOverlay } from '@roleypoly/design-system/atoms/sparkle'; +import { Toggle } from '@roleypoly/design-system/atoms/toggle'; +import { + AmbientLarge, + LargeText, + SmallTitle, +} from '@roleypoly/design-system/atoms/typography'; import { Role } from '@roleypoly/types'; import { demoData } from '@roleypoly/types/demoData'; import chroma from 'chroma-js'; import * as React from 'react'; -import { FaCheck, FaTimes } from 'react-icons/fa'; -import { DiscordBase, DiscordRole } from './WhyNoRoles.styled'; +import { DiscordBase, DiscordRole, Do, Dont, Why } from './WhyNoRoles.styled'; const adminRoles: Role[] = [ { @@ -60,7 +65,11 @@ const Example = (props: { roles: Role[]; isGood: boolean }) => ( {props.roles.map((r) => ( - + {r.name} @@ -70,14 +79,50 @@ const Example = (props: { roles: Role[]; isGood: boolean }) => ( ); export const WhyNoRoles = () => ( - - - Good - - - - Baddd - - - +
+

+ Why can't I see my roles? +

+ + + + DO: Roleypoly is above the other roles + + + + + DON'T: Roleypoly is below the other roles + + + + + + + {' '} + Discord doesn't let members/bots with "manage roles" permissions assign roles above + their highest role. + + +

+ Other tips: +

+ +

+ + DO: Roles have no elevated permissions. + Administrator + Manage Roles +
+ + DON'T: Roles cannot have Administrator or Manage Roles permissions. + Administrator + Manage Roles + + + {' '} + These permissions give access to the Roleypoly editor and Discord tools, which can + open your server up to vandalism. + +

+
); diff --git a/packages/web/src/app-router/AppRouter.tsx b/packages/web/src/app-router/AppRouter.tsx index 0d947a0..0b13f64 100644 --- a/packages/web/src/app-router/AppRouter.tsx +++ b/packages/web/src/app-router/AppRouter.tsx @@ -6,6 +6,7 @@ import ErrorPage from '../pages/error'; import LandingPage from '../pages/landing'; import PickerPage from '../pages/picker'; +const WhyNoRoles = React.lazy(() => import('../pages/help/why-no-roles')); const ServersPage = React.lazy(() => import('../pages/servers')); const EditorPage = React.lazy(() => import('../pages/editor')); @@ -50,6 +51,8 @@ export const AppRouter = () => { + + ); diff --git a/packages/web/src/pages/help/why-no-roles.tsx b/packages/web/src/pages/help/why-no-roles.tsx new file mode 100644 index 0000000..39cb18a --- /dev/null +++ b/packages/web/src/pages/help/why-no-roles.tsx @@ -0,0 +1,19 @@ +import { WhyNoRoles } from '@roleypoly/design-system/organisms/help-why-no-roles'; +import { HelpPageTemplate } from '@roleypoly/design-system/templates/help-page'; +import { useAppShellProps } from '../../contexts/app-shell/AppShellContext'; +import { Title } from '../../utils/metaTitle'; + +const WhyNoRolesPage = () => { + const appShellProps = useAppShellProps(); + + return ( + <> + + <HelpPageTemplate {...appShellProps}> + <WhyNoRoles /> + </HelpPageTemplate> + </> + ); +}; + +export default WhyNoRolesPage;