Skip to content

Commit

Permalink
feat: DiscordRewardCard
Browse files Browse the repository at this point in the history
  • Loading branch information
BrickheadJohnny committed Dec 11, 2024
1 parent bbe0179 commit c4292ab
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 3 deletions.
101 changes: 101 additions & 0 deletions src/components/rewards/DiscordRewardCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { useGuild } from "@/app/(dashboard)/[guildUrlName]/hooks/useGuild";
import { IDENTITY_STYLES } from "@/config/constants";
import { env } from "@/lib/env";
import { userOptions } from "@/lib/options";
import type { GuildReward } from "@/lib/schemas/guildReward";
import { DiscordRoleRewardDataSchema } from "@/lib/schemas/roleReward";
import { ArrowSquareOut } from "@phosphor-icons/react/dist/ssr";
import { useQuery } from "@tanstack/react-query";
import { useRouter } from "next/navigation";
import type { FunctionComponent } from "react";
import { buttonVariants } from "../ui/Button";
import {
Tooltip,
TooltipContent,
TooltipPortal,
TooltipTrigger,
} from "../ui/Tooltip";
import { RewardCard, RewardCardButton } from "./RewardCard";
import type { RewardCardProps } from "./types";

export const DiscordRewardCard: FunctionComponent<RewardCardProps> = ({
reward,
}) => {
const router = useRouter();
const {
data: { imageUrl, invite },
} = reward.guildReward as Extract<GuildReward, { type: "DISCORD" }>;
const roleRewardData = DiscordRoleRewardDataSchema.parse(
reward.roleReward.data,
);

const Icon = IDENTITY_STYLES.DISCORD.icon;

const { data: user } = useQuery(userOptions());
const connected = !!user?.identities?.find((i) => i.platform === "DISCORD");

const {
data: { id: guildId },
} = useGuild();

const isGuildMember = !!user?.guilds?.find((g) => g.guildId === guildId);

// TODO: hasRoleAccess instead of isGuildMember

return (
<RewardCard
title="Get role"
description={roleRewardData.roleId}
image={imageUrl ?? <Icon className="size-4" weight="fill" />}
className={IDENTITY_STYLES.DISCORD.borderColorClassName}
>
{!user || !isGuildMember ? (
<Tooltip>
<TooltipTrigger
className={buttonVariants({
// TODO: reusable reward card button className?
className: [
"!opacity-50 mt-auto @[18rem]:ml-auto cursor-not-allowed",
IDENTITY_STYLES.DISCORD.buttonColorsClassName,
],
size: "sm",
})}
>
<span>Go to server</span>
<ArrowSquareOut weight="bold" />
</TooltipTrigger>

<TooltipPortal>
<TooltipContent>
<p>
{!user ? "Sign in to proceed" : "Join guild to check access"}
</p>
</TooltipContent>
</TooltipPortal>
</Tooltip>
) : connected ? (
<RewardCardButton
rightIcon={<ArrowSquareOut weight="bold" />}
className={IDENTITY_STYLES.DISCORD.buttonColorsClassName}
onClick={() => router.push(`https://discord.gg/${invite}`)}
>
Go to server
</RewardCardButton>
) : (
<RewardCardButton
className={IDENTITY_STYLES.DISCORD.buttonColorsClassName}
onClick={
user
? () =>
router.push(
`${env.NEXT_PUBLIC_API}/connect/DISCORD?returnTo=${window.location.href}`,
)
: undefined
}
>
Connect Discord
</RewardCardButton>
)}
</RewardCard>
);
};
2 changes: 1 addition & 1 deletion src/components/rewards/PointsRewardCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const PointsRewardCard: FunctionComponent<RewardCardProps> = ({
const {
id,
data: { name },
} = reward.guildReward as Extract<GuildReward, { type: "POINTS" }>; // Should we use Zod here?
} = reward.guildReward as Extract<GuildReward, { type: "POINTS" }>;
const roleRewardData = PointsRoleRewardDataSchema.parse(
reward.roleReward.data,
);
Expand Down
2 changes: 2 additions & 0 deletions src/components/rewards/rewardCards.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { DiscordRewardCard } from "./DiscordRewardCard";
import { GuildPermissionRewardCard } from "./GuildPermissionRewardCard";
import { PointsRewardCard } from "./PointsRewardCard";

export const rewardCards = {
GUILD: GuildPermissionRewardCard,
POINTS: PointsRewardCard,
DISCORD: DiscordRewardCard,
} as const; // TODO: add "satisfies..."
6 changes: 4 additions & 2 deletions src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ import { DiscordLogo } from "@phosphor-icons/react/dist/ssr";

export const IDENTITY_STYLES = {
DISCORD: {
mainColorClassName: "bg-indigo-500",
bgColorClassName: "bg-indigo-500",
borderColorClassName: "border-indigo-500",
buttonColorsClassName:
"bg-indigo-500 hover:bg-indigo-600 active:bg-indigo-700 dark:hover:bg-indigo-400 dark:active:bg-indigo-300",
icon: DiscordLogo,
},
} satisfies Record<
IdentityType,
{
mainColorClassName: string;
bgColorClassName: string;
borderColorClassName: string;
buttonColorsClassName: string;
icon: Icon;
}
Expand Down

0 comments on commit c4292ab

Please sign in to comment.