From eadb255aff65bc61db870adf34f9c4bd384a5b3e Mon Sep 17 00:00:00 2001 From: valid Date: Wed, 13 Dec 2023 17:47:07 +0100 Subject: [PATCH] wip: move roles to columns --- .../CrmRoleAccessIndicator.tsx | 30 ++++++++++ .../components/CrmRoleAccessIndicatorUI.tsx | 44 +++++++++++++++ .../crm/CrmRoleAccessIndicator/index.ts | 3 + .../[guild]/crm/CustomizeViewModal.tsx | 55 +++++++++++++++++-- src/components/[guild]/crm/RoleTags.tsx | 32 ++++++++++- src/pages/[guild]/members.tsx | 23 +++++++- 6 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 src/components/[guild]/crm/CrmRoleAccessIndicator/CrmRoleAccessIndicator.tsx create mode 100644 src/components/[guild]/crm/CrmRoleAccessIndicator/components/CrmRoleAccessIndicatorUI.tsx create mode 100644 src/components/[guild]/crm/CrmRoleAccessIndicator/index.ts diff --git a/src/components/[guild]/crm/CrmRoleAccessIndicator/CrmRoleAccessIndicator.tsx b/src/components/[guild]/crm/CrmRoleAccessIndicator/CrmRoleAccessIndicator.tsx new file mode 100644 index 0000000000..16d94b634a --- /dev/null +++ b/src/components/[guild]/crm/CrmRoleAccessIndicator/CrmRoleAccessIndicator.tsx @@ -0,0 +1,30 @@ +import { PopoverHeader } from "@chakra-ui/react" +import { POPOVER_HEADER_STYLES } from "components/[guild]/Requirements/components/RequiementAccessIndicator" +import { Check, X } from "phosphor-react" +import { CrmRole } from "../useMembers" +import CrmRoleAccessIndicatorUI from "./components/CrmRoleAccessIndicatorUI" + +type Props = { + memberRole: CrmRole +} + +const CrmRoleAccessIndicator = ({ memberRole }: Props) => { + if (!memberRole) + return ( + + Role not satisfied + + ) + + return ( + + Role satisfied + + ) +} + +export default CrmRoleAccessIndicator diff --git a/src/components/[guild]/crm/CrmRoleAccessIndicator/components/CrmRoleAccessIndicatorUI.tsx b/src/components/[guild]/crm/CrmRoleAccessIndicator/components/CrmRoleAccessIndicatorUI.tsx new file mode 100644 index 0000000000..a2a621bf45 --- /dev/null +++ b/src/components/[guild]/crm/CrmRoleAccessIndicator/components/CrmRoleAccessIndicatorUI.tsx @@ -0,0 +1,44 @@ +import { + Center, + Icon, + Popover, + PopoverArrow, + PopoverContent, + PopoverTrigger, + Portal, + Tag, + Text, +} from "@chakra-ui/react" +import { FC, PropsWithChildren } from "react" + +type Props = { + colorScheme: string + icon: FC + amount?: number +} + +const CrmRoleAccessIndicatorUI = ({ + colorScheme, + icon, + amount, + children, +}: PropsWithChildren) => ( +
+ + + + + {amount && {amount.toFixed(2)}} + + + + + {children} + + + + +
+) + +export default CrmRoleAccessIndicatorUI diff --git a/src/components/[guild]/crm/CrmRoleAccessIndicator/index.ts b/src/components/[guild]/crm/CrmRoleAccessIndicator/index.ts new file mode 100644 index 0000000000..2ae2b54303 --- /dev/null +++ b/src/components/[guild]/crm/CrmRoleAccessIndicator/index.ts @@ -0,0 +1,3 @@ +import CrmRoleAccessIndicator from "./CrmRoleAccessIndicator" + +export default CrmRoleAccessIndicator diff --git a/src/components/[guild]/crm/CustomizeViewModal.tsx b/src/components/[guild]/crm/CustomizeViewModal.tsx index 7b868d33e6..4eed0390d0 100644 --- a/src/components/[guild]/crm/CustomizeViewModal.tsx +++ b/src/components/[guild]/crm/CustomizeViewModal.tsx @@ -11,10 +11,12 @@ import { useColorModeValue, } from "@chakra-ui/react" import { Column, Table } from "@tanstack/react-table" +import SimpleRoleTag from "components/analytics/MembersChart/components/SimpleRoleTag" import { Modal } from "components/common/Modal" import { Reorder } from "framer-motion" import { DotsSixVertical } from "phosphor-react" -import { useState } from "react" +import { useEffect, useState } from "react" +import useGuild from "../hooks/useGuild" import { Member } from "./useMembers" type Props = { @@ -35,6 +37,10 @@ const CustomizeViewModal = ({ isOpen, onClose, table }: Props) => { const columns = table.getAllColumns() const [localOrder, setLocalOrder] = useState(() => transformToLocalOrder(table)) + useEffect(() => { + setLocalOrder(transformToLocalOrder(table)) + }, [columns]) + const setTableOrder = () => { const newOrder = transformToTableOrder(localOrder) /** @@ -47,7 +53,7 @@ const CustomizeViewModal = ({ isOpen, onClose, table }: Props) => { } return ( - + Customize shown columns @@ -65,7 +71,14 @@ const CustomizeViewModal = ({ isOpen, onClose, table }: Props) => { onDragEnd={setTableOrder} style={{ position: "relative" }} // needed for the auto-applied zIndex to work > - col.id === colId)} /> + {colId.startsWith("role_") ? ( + col.id === colId)} + roleId={parseInt(colId.split("_")[1])} + /> + ) : ( + col.id === colId)} /> + )} ))} @@ -87,6 +100,7 @@ const ColumnSelector = ({ column, isDisabled }: SelectorProps) => { mb="2" bg={bg} borderRadius="xl" + boxShadow={"xs"} cursor={!isDisabled && "grab"} > @@ -135,10 +149,41 @@ const ColumnSelector = ({ column, isDisabled }: SelectorProps) => { ) } +type RoleSelectorProps = { column: Column; roleId: number } + +const RoleColumnSelector = ({ column, roleId }: RoleSelectorProps) => { + const bg = useColorModeValue("white", "#343437") + const { roles } = useGuild() + + const role = roles.find((r) => r.id === roleId) + + return ( + + + + + + + + + ) +} + const transformToLocalOrder = (table) => { - const columnOrder = table.getState().columnOrder + const res = [...table.getState().columnOrder] const columnIds = table.getAllLeafColumns().map((col) => col.id) - const res = columnOrder.length ? columnOrder : columnIds + columnIds.forEach((colId) => !res.includes(colId) && res.push(colId)) // remove 'select' and 'identity' res.splice(0, 2) diff --git a/src/components/[guild]/crm/RoleTags.tsx b/src/components/[guild]/crm/RoleTags.tsx index 3bb78e2855..136e476135 100644 --- a/src/components/[guild]/crm/RoleTags.tsx +++ b/src/components/[guild]/crm/RoleTags.tsx @@ -16,7 +16,9 @@ import { } from "@chakra-ui/react" import { Column } from "@tanstack/react-table" import Button from "components/common/Button" -import { Funnel } from "phosphor-react" +import { useAtom } from "jotai" +import { shownRoleColumnsAtom } from "pages/[guild]/members" +import { ArrowFatRight, Funnel, X } from "phosphor-react" import { Visibility } from "types" import pluralize from "utils/pluralize" import ClickableTagPopover from "../activity/ActivityLogAction/components/ClickableTagPopover" @@ -176,6 +178,7 @@ export const ClickableCrmRoleTag = ({ + } > @@ -206,4 +209,31 @@ const FilterByCrmRole = ({ roleId, column, onFilter }) => { ) } +const MoveRoleToColumn = ({ roleId }) => { + const [shownRoleColumns, setShownRoleColumnsAtom] = useAtom(shownRoleColumnsAtom) + + const isAlreadyColumn = shownRoleColumns.includes(roleId) + + const onClick = () => { + setShownRoleColumnsAtom((prevValue) => + isAlreadyColumn + ? prevValue.filter((id) => id !== roleId) + : [...prevValue, roleId] + ) + } + + return ( + + ) +} + export default RoleTags diff --git a/src/pages/[guild]/members.tsx b/src/pages/[guild]/members.tsx index f98a14e924..b5b9d5fff5 100644 --- a/src/pages/[guild]/members.tsx +++ b/src/pages/[guild]/members.tsx @@ -11,6 +11,7 @@ import CrmTableWrapper from "components/[guild]/crm/CRMTable/CrmTableWrapper" import CrmTbody from "components/[guild]/crm/CRMTable/CrmTbody" import CrmThead from "components/[guild]/crm/CRMTable/CrmThead" import CrmMenu from "components/[guild]/crm/CrmMenu" +import CrmRoleAccessIndicator from "components/[guild]/crm/CrmRoleAccessIndicator" import FilterByRoles from "components/[guild]/crm/FilterByRoles" import Identities from "components/[guild]/crm/Identities" import IdentitiesExpansionToggle from "components/[guild]/crm/IdentitiesExpansionToggle" @@ -22,10 +23,11 @@ import { parseFiltersFromQuery, parseSortingFromQuery, } from "components/[guild]/crm/transformTableStateToAndFromQuery" -import useMembers, { Member } from "components/[guild]/crm/useMembers" +import useMembers, { CrmRole, Member } from "components/[guild]/crm/useMembers" import useGuild from "components/[guild]/hooks/useGuild" import GuildLogo from "components/common/GuildLogo" import Layout from "components/common/Layout" +import { atom, useAtom } from "jotai" import Head from "next/head" import { useRouter } from "next/router" import ErrorPage from "pages/_error" @@ -124,9 +126,26 @@ const columns = [ }), ] +export const shownRoleColumnsAtom = atom([]) + const GuildPage = (): JSX.Element => { const { textColor, localThemeColor, localBackgroundImage } = useThemeContext() const { name, roles, imageUrl } = useGuild() + const [shownRoleColumns] = useAtom(shownRoleColumnsAtom) + + const roleColumns = useMemo( + () => + shownRoleColumns.map((roleId) => ({ + accessorKey: `role_${roleId}`, + accessorFn: (row) => + Object.values(row.roles) + .flat() + .find((role: CrmRole) => role.roleId === roleId), + header: () => roles.find((role) => role.id === roleId)?.name, + cell: (info) => , + })), + [shownRoleColumns] + ) const router = useRouter() const [columnFilters, setColumnFilters] = useState(() => @@ -166,7 +185,7 @@ const GuildPage = (): JSX.Element => { const table = useReactTable({ data: useMemo(() => data ?? [], [data]), - columns, + columns: useMemo(() => [...columns, ...roleColumns], [roleColumns]), state: { columnFilters, sorting,