Skip to content

Commit

Permalink
feat: DiscordCardWarning component (#1474)
Browse files Browse the repository at this point in the history
* cleanup(Reward): remove `GoogleCardWarning` component

* fix(GoogleCardWarning): remove unused logic/comments + refactor

* feat(AccessedGuildPlatformCard): always display warning component

* feat: `CardWarningComponentBase` component

* cleanup: remove empty imports

* feat: `DiscordCardWarning` component

* copy(DiscordCardWarning): add "anymore" to the end

* fix(AccessedGuildPlatformCard): destructure `useRolePlatform` return value

---------

Co-authored-by: valid <[email protected]>
  • Loading branch information
BrickheadJohnny and dovalid authored Sep 11, 2024
1 parent 9ecc70c commit 14f0f25
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import PlatformCard from "components/[guild]/RolePlatforms/components/PlatformCa
import { useRolePlatform } from "components/[guild]/RolePlatforms/components/RolePlatformProvider"
import useGuild from "components/[guild]/hooks/useGuild"
import useGuildPermission from "components/[guild]/hooks/useGuildPermission"
import rewards from "rewards"
import { cardPropsHooks } from "rewards/cardPropsHooks"
import rewardComponents from "rewards/components"
import rewardComponentsConfig from "rewards/components"
import { PlatformName, PlatformType } from "types"
import PlatformAccessButton from "./PlatformAccessButton"

Expand All @@ -13,25 +12,29 @@ const AccessedGuildPlatformCard = () => {
const { isDetailed } = useGuild()
const { isAdmin } = useGuildPermission()

if (!rewards[PlatformType[guildPlatform.platformId]]) return null
const rewardComponents =
rewardComponentsConfig[PlatformType[guildPlatform.platformId] as PlatformName]
const useCardProps = cardPropsHooks[PlatformType[guildPlatform.platformId]]

if (!rewardComponents || !useCardProps) return null

const {
cardMenuComponent: PlatformCardMenu,
cardWarningComponent: PlatformCardWarning,
cardButton: PlatformCardButton,
} = rewardComponents[PlatformType[guildPlatform.platformId] as PlatformName]
const useCardProps = cardPropsHooks[PlatformType[guildPlatform.platformId]]
} = rewardComponents

return (
<PlatformCard
usePlatformCardProps={useCardProps}
guildPlatform={guildPlatform}
cornerButton={
isAdmin && isDetailed && PlatformCardMenu ? (
<PlatformCardMenu platformGuildId={guildPlatform.platformGuildId} />
) : PlatformCardWarning ? (
<PlatformCardWarning guildPlatform={guildPlatform} />
) : null
<>
{PlatformCardWarning && <PlatformCardWarning />}
{isAdmin && isDetailed && PlatformCardMenu && (
<PlatformCardMenu platformGuildId={guildPlatform.platformGuildId} />
)}
</>
}
h="full"
p={{ base: 3, sm: 4 }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { ColorPicker } from "@/components/ui/ColorPicker"
import { FormControl, FormLabel } from "@chakra-ui/react"
import { useThemeContext } from "components/[guild]/ThemeContext"
import FormErrorMessage from "components/common/FormErrorMessage"
import {} from "react"
import { useFormContext } from "react-hook-form"

type Props = {
Expand Down
19 changes: 4 additions & 15 deletions src/components/[guild]/RoleCard/components/Reward.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import useMembership, {
} from "components/explorer/hooks/useMembership"
import { useMemo, useState } from "react"
import rewards from "rewards"
import GoogleCardWarning from "rewards/Google/GoogleCardWarning"
import rewardComponents from "rewards/components"
import { PlatformType, RolePlatform } from "types"
import capitalize from "utils/capitalize"
Expand Down Expand Up @@ -121,20 +120,10 @@ const Reward = ({ role, platform, withLink, isLinkColorful }: RewardProps) => {
</>
}
rightElement={
<>
<Visibility
visibilityRoleId={platform.visibilityRoleId}
entityVisibility={platform.visibility}
/>

{platform.guildPlatform?.platformId === PlatformType.GOOGLE && (
<GoogleCardWarning
guildPlatform={platform.guildPlatform}
roleMemberCount={role.memberCount}
size="sm"
/>
)}
</>
<Visibility
visibilityRoleId={platform.visibilityRoleId}
entityVisibility={platform.visibility}
/>
}
/>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const DCServerCard = ({
isValidating,
permissions: existingPermissions,
error,
} = useServerPermissions(serverData?.id, !isUsedInCurrentGuild)
} = useServerPermissions(serverData?.id, { shouldFetch: !isUsedInCurrentGuild })

const onSelect = async () => {
try {
Expand Down
4 changes: 2 additions & 2 deletions src/components/common/RewardCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ const RewardCard = ({
{...rest}
>
{cornerButton && (
<Box position="absolute" top={2} right={2}>
<HStack position="absolute" top={2} right={2}>
{cornerButton}
</Box>
</HStack>
)}
<Flex
justifyContent={"space-between"}
Expand Down
14 changes: 10 additions & 4 deletions src/hooks/useServerPermissions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { REQUIRED_PERMISSIONS } from "components/[guild]/DiscordBotPermissionsChecker"
import { SWRConfiguration } from "swr"
import useSWRImmutable from "swr/immutable"
import fetcher from "utils/fetcher"

Expand Down Expand Up @@ -47,19 +48,24 @@ function mapPermissions(permissions: PermissionsResponse) {
}
}

export default function useServerPermissions(serverId: string, shouldFetch = true) {
const shouldFetchFinal = shouldFetch && serverId?.length > 0
export default function useServerPermissions(
serverId: string,
config: SWRConfiguration & { shouldFetch?: boolean } = { shouldFetch: undefined }
) {
const { shouldFetch, ...swrConfig } = config
const shouldFetchFinal =
(typeof shouldFetch === "undefined" || shouldFetch) && serverId?.length > 0
const { data, error, isLoading, isValidating, mutate } = useSWRImmutable<
ReturnType<typeof mapPermissions>
>(
shouldFetchFinal ? `/v2/discord/servers/${serverId}/permissions` : null,
(url) => fetcher(url).then(mapPermissions),
{ shouldRetryOnError: false, revalidateOnMount: false }
{ shouldRetryOnError: false, revalidateOnMount: false, ...swrConfig }
)

return {
permissions: data,
rolePrders: data?.roleOrders,
roleOrders: data?.roleOrders,
error,
isLoading,
isValidating,
Expand Down
41 changes: 41 additions & 0 deletions src/rewards/Discord/DiscordCardWarning.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useRolePlatform } from "components/[guild]/RolePlatforms/components/RolePlatformProvider"
import useGuildPermission from "components/[guild]/hooks/useGuildPermission"
import useServerPermissions from "hooks/useServerPermissions"
import { ReactNode } from "react"
import { CardWarningComponentBase } from "rewards/components/CardWarningComponentBase"

const DiscordCardWarning = (): ReactNode => {
const { isAdmin } = useGuildPermission()
if (!isAdmin) return null

return <DiscordCardWarningWithLogic />
}

const DiscordCardWarningWithLogic = (): ReactNode => {
const rolePlatform = useRolePlatform()
const { roleOrders } = useServerPermissions(
// biome-ignore lint/style/noNonNullAssertion: we can be confident that platformGuildId exists at this point
rolePlatform.guildPlatform?.platformGuildId!,
{
revalidateOnMount: true,
}
)

const existingDiscordRoles = roleOrders?.map((role) => role.discordRoleId)

if (
!existingDiscordRoles ||
!rolePlatform.platformRoleId ||
existingDiscordRoles.includes(rolePlatform.platformRoleId)
)
return null

return (
<CardWarningComponentBase>
This reward won't be assigned to users, because the connected Discord role
doesn't exist anymore
</CardWarningComponentBase>
)
}

export { DiscordCardWarning }
2 changes: 2 additions & 0 deletions src/rewards/Discord/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import dynamic from "next/dynamic"
import { AddRewardPanelLoadingSpinner } from "rewards/components/AddRewardPanelLoadingSpinner"
import { RewardComponentsData } from "rewards/types"
import DiscordCardMenu from "./DiscordCardMenu"
import { DiscordCardWarning } from "./DiscordCardWarning"

export default {
cardMenuComponent: DiscordCardMenu,
cardWarningComponent: DiscordCardWarning,
AddRewardPanel: dynamic(
() =>
import(
Expand Down
74 changes: 14 additions & 60 deletions src/rewards/Google/GoogleCardWarning.tsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,24 @@
import {
Icon,
Popover,
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverTrigger,
Portal,
} from "@chakra-ui/react"
import { WarningCircle } from "@phosphor-icons/react"
import { useRolePlatform } from "components/[guild]/RolePlatforms/components/RolePlatformProvider"
import useGuild from "components/[guild]/hooks/useGuild"
import { GuildPlatform } from "types"
import { ReactNode } from "react"
import { CardWarningComponentBase } from "rewards/components/CardWarningComponentBase"

type Props = {
guildPlatform: GuildPlatform
roleMemberCount?: number
size?: "sm" | "md"
}

const GoogleCardWarning = ({
guildPlatform,
roleMemberCount,
size = "md",
}: Props): JSX.Element => {
const GoogleCardWarning = (): ReactNode => {
const rolePlatform = useRolePlatform()
const { roles } = useGuild()
const rolesWithPlatform = roles.filter((role) =>
role.rolePlatforms?.some(
(rolePlatform) => rolePlatform.guildPlatformId === guildPlatform?.id
)
)
// const eligibleMembers = useUniqueMembers(rolesWithPlatform)
const roleMemberCount =
roles?.find((role) => role.rolePlatforms.some((rp) => rp.id === rolePlatform.id))
?.memberCount ?? 0

// if (eligibleMembers.length < 600) return null
if (
roleMemberCount < 0 ||
!rolesWithPlatform?.some((role) => role.memberCount >= 600)
)
return null
if (roleMemberCount <= 600) return null

return (
<Popover trigger="hover" openDelay={0}>
<PopoverTrigger>
<Icon
as={WarningCircle}
color="orange.300"
weight="fill"
// boxSize={size === "sm" ? 5 : 6}
boxSize={6}
p={size === "sm" ? "2px" : 0}
tabIndex={0}
/>
</PopoverTrigger>
<Portal>
<PopoverContent>
<PopoverArrow />
<PopoverBody>
{/* {`Google limits documentum sharing to 600 users, and there're already ${eligibleMembers.length}
eligible members, so you might not get access to this reward.`} */}
{`Google limits documentum sharing to 600 users, and there're already ${
roleMemberCount ??
rolesWithPlatform?.find((role) => role.memberCount >= 600)?.memberCount
}
<CardWarningComponentBase>
{`Google limits documentum sharing to 600 users, and there're already ${
roleMemberCount
}
eligible members, so you might not get access to this reward.`}
</PopoverBody>
</PopoverContent>
</Portal>
</Popover>
</CardWarningComponentBase>
)
}

Expand Down
35 changes: 35 additions & 0 deletions src/rewards/components/CardWarningComponentBase.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
Icon,
Popover,
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverTrigger,
Portal,
} from "@chakra-ui/react"
import { WarningCircle } from "@phosphor-icons/react"
import { PropsWithChildren, ReactNode } from "react"

const CardWarningComponentBase = ({ children }: PropsWithChildren): ReactNode => {
return (
<Popover trigger="hover" openDelay={0}>
<PopoverTrigger>
<Icon
as={WarningCircle}
color="orange.300"
weight="fill"
boxSize={6}
tabIndex={0}
/>
</PopoverTrigger>
<Portal>
<PopoverContent>
<PopoverArrow />
<PopoverBody>{children}</PopoverBody>
</PopoverContent>
</Portal>
</Popover>
)
}

export { CardWarningComponentBase }
6 changes: 5 additions & 1 deletion src/rewards/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export type RewardData = {

export type RewardComponentsData = {
cardMenuComponent?: (props: any) => JSX.Element
cardWarningComponent?: (props: any) => JSX.Element
cardWarningComponent?: ComponentType<unknown>
cardButton?: (props: any) => JSX.Element
AddRewardPanel?: ComponentType<AddRewardPanelProps>
SmallRewardPreview?: ComponentType<RewardProps>
Expand Down Expand Up @@ -80,3 +80,7 @@ export type CardPropsHook = (guildPlatform: GuildPlatformWithOptionalId) => {
info?: string | JSX.Element
link?: string
}

export type CardWarningComponentProps = {
rolePlatform: NonNullable<RoleFormType["rolePlatforms"]>[number]
}

0 comments on commit 14f0f25

Please sign in to comment.