setCategoryData(category)}
+ uncategorizedRoles={roleCategory}
+ guildRoles={[...roleCategory, ...roleCategory2]}
+ />
+ );
+};
diff --git a/src/design-system/molecules/editor-category/EditorCategory.styled.ts b/src/design-system/molecules/editor-category/EditorCategory.styled.ts
new file mode 100644
index 0000000..e9a7fb0
--- /dev/null
+++ b/src/design-system/molecules/editor-category/EditorCategory.styled.ts
@@ -0,0 +1,7 @@
+import * as _ from 'styled-components'; // eslint-disable-line no-duplicate-imports
+import styled from 'styled-components';
+
+export const RoleContainer = styled.div`
+ display: flex;
+ margin: 10px;
+`;
diff --git a/src/design-system/molecules/editor-category/EditorCategory.tsx b/src/design-system/molecules/editor-category/EditorCategory.tsx
new file mode 100644
index 0000000..0132f99
--- /dev/null
+++ b/src/design-system/molecules/editor-category/EditorCategory.tsx
@@ -0,0 +1,150 @@
+import * as React from 'react';
+import { HorizontalSwitch } from 'roleypoly/src/design-system/atoms/horizontal-switch';
+import { Space } from 'roleypoly/src/design-system/atoms/space';
+import {
+ TextInput,
+ TextInputWithIcon,
+} from 'roleypoly/src/design-system/atoms/text-input';
+import { Text } from 'roleypoly/src/design-system/atoms/typography';
+import { Popover } from 'roleypoly/src/design-system/atoms/popover';
+import { FaderOpacity } from 'roleypoly/src/design-system/atoms/fader';
+import { RoleSearch } from 'roleypoly/src/design-system/molecules/role-search';
+import {
+ Category,
+ CategoryType,
+ Role as RoleType,
+} from 'roleypoly/src/design-system/shared-types';
+import { Role } from 'roleypoly/src/design-system/atoms/role';
+import { GoSearch } from 'react-icons/go';
+import { RoleContainer } from './EditorCategory.styled';
+
+type Props = {
+ category: Category;
+ uncategorizedRoles: RoleType[];
+ guildRoles: RoleType[];
+ onChange: (category: Category) => void;
+};
+
+const typeEnumToSwitch = (typeData: CategoryType) => {
+ if (typeData === CategoryType.SINGLE) {
+ return 'Single';
+ } else {
+ return 'Multiple';
+ }
+};
+
+const switchToTypeEnum = (typeData: 'Single' | 'Multiple') => {
+ if (typeData === 'Single') {
+ return CategoryType.SINGLE;
+ } else {
+ return CategoryType.MULTI;
+ }
+};
+
+export const EditorCategory = (props: Props) => {
+ const [roleSearchPopoverActive, setRoleSearchPopoverActive] = React.useState(false);
+ const [roleSearchTerm, updateSearchTerm] = React.useState('');
+
+ const onUpdate = (
+ key: keyof typeof props.category,
+ pred?: (newValue: any) => any
+ ) => (newValue: any) => {
+ props.onChange({
+ ...props.category,
+ [key]: pred ? pred(newValue) : newValue,
+ });
+ };
+
+ const handleRoleSelect = (role: RoleType) => {
+ setRoleSearchPopoverActive(false);
+ updateSearchTerm('');
+ props.onChange({
+ ...props.category,
+ rolesList: [...props.category.rolesList, role.id],
+ });
+ };
+
+ const handleRoleDeselect = (role: RoleType) => () => {
+ props.onChange({
+ ...props.category,
+ rolesList: props.category.rolesList.filter((x) => x !== role.id),
+ });
+ };
+
+ return (
+
+
Category Name
+
x.target.value)}
+ />
+
+
+
+ Selection Type
+
+
+
+
+
+
+ Visiblity
+
+ a === 'Hidden')}
+ />
+
+
+
+ Roles
+ setRoleSearchPopoverActive(false)}
+ >
+ {() => (
+ updateSearchTerm(newTerm)}
+ />
+ )}
+
+
+ }
+ placeholder={'Type or drag a role...'}
+ onFocus={() => setRoleSearchPopoverActive(true)}
+ value={roleSearchTerm}
+ onChange={(x) => updateSearchTerm(x.target.value)}
+ />
+
+ {props.category.rolesList.map((id) => {
+ const role = props.guildRoles.find((x) => x.id === id);
+ if (!role) {
+ return <>>;
+ }
+
+ return (
+
+ );
+ })}
+
+
+
+ );
+};
diff --git a/src/design-system/molecules/editor-category/index.ts b/src/design-system/molecules/editor-category/index.ts
new file mode 100644
index 0000000..67c2556
--- /dev/null
+++ b/src/design-system/molecules/editor-category/index.ts
@@ -0,0 +1 @@
+export * from './EditorCategory';
diff --git a/src/design-system/molecules/help-page-base/BUILD.bazel b/src/design-system/molecules/help-page-base/BUILD.bazel
new file mode 100644
index 0000000..f94e5ca
--- /dev/null
+++ b/src/design-system/molecules/help-page-base/BUILD.bazel
@@ -0,0 +1,10 @@
+load("//hack/bazel/js:react.bzl", "react_library")
+
+package(default_visibility = ["//visibility:public"])
+
+react_library(
+ name = "help-page-base",
+ deps = [
+ "//src/design-system/atoms/colors",
+ ],
+)
diff --git a/src/design-system/molecules/role-search/RoleSearch.stories.tsx b/src/design-system/molecules/role-search/RoleSearch.stories.tsx
new file mode 100644
index 0000000..b4ec3ee
--- /dev/null
+++ b/src/design-system/molecules/role-search/RoleSearch.stories.tsx
@@ -0,0 +1,14 @@
+import * as React from 'react';
+import { RoleSearch } from './RoleSearch';
+import { roleCategory } from 'roleypoly/src/design-system/shared-types/storyData';
+
+export default {
+ title: 'Molecules/Role Search',
+ component: RoleSearch,
+ args: {
+ roles: roleCategory,
+ searchTerm: '',
+ },
+};
+
+export const Search = (args) => ;
diff --git a/src/design-system/molecules/role-search/RoleSearch.tsx b/src/design-system/molecules/role-search/RoleSearch.tsx
new file mode 100644
index 0000000..d638ecd
--- /dev/null
+++ b/src/design-system/molecules/role-search/RoleSearch.tsx
@@ -0,0 +1,57 @@
+import styled from 'styled-components';
+import Fuse from 'fuse.js';
+import * as React from 'react';
+import { GoSearch } from 'react-icons/go';
+import { Role } from 'roleypoly/src/design-system/atoms/role';
+import { Space } from 'roleypoly/src/design-system/atoms/space';
+import { TextInputWithIcon } from 'roleypoly/src/design-system/atoms/text-input';
+import { Role as RoleType } from 'roleypoly/src/design-system/shared-types';
+
+type Props = {
+ roles: RoleType[];
+ placeholder?: string;
+ onSelect: (role: RoleType) => void;
+ onSearchUpdate: (newTerm: string) => void;
+ searchTerm: string;
+};
+
+export const RoleSearch = (props: Props) => {
+ const fuse = new Fuse(props.roles, { includeScore: true, keys: ['name'] });
+ const results =
+ props.searchTerm !== ''
+ ? fuse.search(props.searchTerm)
+ : props.roles.map((role) => ({
+ item: role,
+ }));
+
+ const handleClick = (role: RoleType) => () => {
+ props.onSelect(role);
+ };
+
+ return (
+
+ }
+ placeholder={props.placeholder || 'Search or drag a role...'}
+ value={props.searchTerm}
+ onChange={(x) => props.onSearchUpdate(x.target.value)}
+ />
+
+ {results.map((resultRole, idx) => (
+
+
+
+ ))}
+
+ );
+};
+
+const RoleInliner = styled.div`
+ display: flex;
+ margin: 5px 0;
+`;
diff --git a/src/design-system/molecules/role-search/index.ts b/src/design-system/molecules/role-search/index.ts
new file mode 100644
index 0000000..10fd011
--- /dev/null
+++ b/src/design-system/molecules/role-search/index.ts
@@ -0,0 +1 @@
+export * from './RoleSearch';
diff --git a/src/design-system/organisms/editor/EditorShell.stories.tsx b/src/design-system/organisms/editor/EditorShell.stories.tsx
new file mode 100644
index 0000000..eef53e3
--- /dev/null
+++ b/src/design-system/organisms/editor/EditorShell.stories.tsx
@@ -0,0 +1,10 @@
+import * as React from 'react';
+import { EditorShell } from './EditorShell';
+import { guildEnum } from 'roleypoly/src/design-system/shared-types/storyData';
+
+export default {
+ title: 'Organisms/Editor',
+ component: EditorShell,
+};
+
+export const Shell = () => ;
diff --git a/src/design-system/organisms/editor/EditorShell.styled.ts b/src/design-system/organisms/editor/EditorShell.styled.ts
new file mode 100644
index 0000000..40f7dae
--- /dev/null
+++ b/src/design-system/organisms/editor/EditorShell.styled.ts
@@ -0,0 +1,8 @@
+import styled from 'styled-components';
+import { palette } from 'roleypoly/src/design-system/atoms/colors';
+
+export const CategoryContainer = styled.div`
+ background-color: ${palette.taupe100};
+ padding: 10px;
+ margin: 15px 0;
+`;
diff --git a/src/design-system/organisms/editor/EditorShell.tsx b/src/design-system/organisms/editor/EditorShell.tsx
new file mode 100644
index 0000000..e186e17
--- /dev/null
+++ b/src/design-system/organisms/editor/EditorShell.tsx
@@ -0,0 +1,31 @@
+import * as React from 'react';
+import { TabView, Tab } from 'roleypoly/src/design-system/atoms/tab-view';
+import { PresentableGuild } from 'roleypoly/src/design-system/shared-types';
+import { EditorCategory } from '../../molecules/editor-category';
+import { CategoryContainer } from './EditorShell.styled';
+
+type Props = {
+ guild: PresentableGuild;
+};
+
+export const EditorShell = (props: Props) => (
+
+ {() => }
+ {() => hi2!
}
+
+);
+
+const RolesTab = (props: Props) => (
+
+ {props.guild.data.categoriesList.map((category, idx) => (
+
+ console.log(x)}
+ />
+
+ ))}
+
+);
diff --git a/src/design-system/organisms/editor/index.ts b/src/design-system/organisms/editor/index.ts
new file mode 100644
index 0000000..80da6a4
--- /dev/null
+++ b/src/design-system/organisms/editor/index.ts
@@ -0,0 +1 @@
+export * from './EditorShell';
diff --git a/src/design-system/organisms/preauth/BUILD.bazel b/src/design-system/organisms/preauth/BUILD.bazel
index 9748b14..23fecaa 100644
--- a/src/design-system/organisms/preauth/BUILD.bazel
+++ b/src/design-system/organisms/preauth/BUILD.bazel
@@ -3,7 +3,7 @@ load("//hack/bazel/js:react.bzl", "react_library")
package(default_visibility = ["//visibility:public"])
react_library(
- name = "role-picker",
+ name = "preauth",
deps = [
"react-icons",
"//src/design-system/atoms/button",
diff --git a/tsconfig.json b/tsconfig.json
index e14d668..7453df6 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -19,7 +19,7 @@
"declaration": true,
"moduleResolution": "node",
"paths": {
- "roleypoly/*": ["./*", "./bazel-bin/*"]
+ "roleypoly/*": ["./*", "./dist/bin/*"]
}
}
}
diff --git a/yarn.lock b/yarn.lock
index d37a829..d79c6a6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7082,6 +7082,11 @@ fuse.js@^3.6.1:
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.6.1.tgz#7de85fdd6e1b3377c23ce010892656385fd9b10c"
integrity sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw==
+fuse.js@^6.4.2:
+ version "6.4.2"
+ resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-6.4.2.tgz#bd1400164de6562c077baeaa54ed642b4c2fca62"
+ integrity sha512-jyy+zOtV96ylMqOGpVjAWQfvEkfTtuJRjsOC6pjReeju8SoDZ2vgFF6eur0a8fxsVwwcpdt3ieaQQeLdkqXH1Q==
+
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"