diff --git a/package.json b/package.json index 0dfc2cae6a..44d83679a6 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "build-storybook": "storybook build" }, "dependencies": { + "@guildxyz/bev3": "^0.0.4", "@hookform/resolvers": "^3.9.1", "@phosphor-icons/react": "^2.1.7", "@radix-ui/react-avatar": "^1.1.1", diff --git a/src/actions/auth.ts b/src/actions/auth.ts index 80bc7158ef..62f761b130 100644 --- a/src/actions/auth.ts +++ b/src/actions/auth.ts @@ -2,22 +2,10 @@ import { GUILD_AUTH_COOKIE_NAME } from "@/config/constants"; import { env } from "@/lib/env"; +import { authSchema, tokenSchema } from "@/lib/schemas/user"; import { jwtDecode } from "jwt-decode"; import { cookies } from "next/headers"; import { redirect } from "next/navigation"; -import { z } from "zod"; - -const authSchema = z.object({ - message: z.string(), - token: z.string(), - userId: z.string().uuid(), -}); - -const tokenSchema = z.object({ - userId: z.string().uuid(), - exp: z.number().positive().int(), - iat: z.number().positive().int(), -}); export const signIn = async ({ message, diff --git a/src/app/(dashboard)/[guildId]/components/JoinButton.tsx b/src/app/(dashboard)/[guildId]/components/JoinButton.tsx index bd22b778c4..53e37f6386 100644 --- a/src/app/(dashboard)/[guildId]/components/JoinButton.tsx +++ b/src/app/(dashboard)/[guildId]/components/JoinButton.tsx @@ -1,11 +1,15 @@ "use client"; import { Button } from "@/components/ui/Button"; +import { Skeleton } from "@/components/ui/Skeleton"; import { GUILD_AUTH_COOKIE_NAME } from "@/config/constants"; import { env } from "@/lib/env"; import { fetcher } from "@/lib/fetcher"; import { getCookie } from "@/lib/getCookie"; import type { Guild } from "@/lib/schemas/guild"; +import { tokenSchema } from "@/lib/schemas/user"; +import { useQuery } from "@tanstack/react-query"; +import { jwtDecode } from "jwt-decode"; const joinGuild = ({ guildId }: { guildId: string }) => { const token = getCookie(GUILD_AUTH_COOKIE_NAME); @@ -20,8 +24,50 @@ const joinGuild = ({ guildId }: { guildId: string }) => { ); }; -export const JoinButton = ({ guild }: { guild: Guild }) => { +const leaveGuild = ({ guildId }: { guildId: string }) => { + const token = getCookie(GUILD_AUTH_COOKIE_NAME); return ( + token && + fetcher(`${env.NEXT_PUBLIC_API}/guild/${guildId}/leave`, { + method: "POST", + headers: { + "X-Auth-Token": token, + }, + }) + ); +}; + +export const JoinButton = ({ guild }: { guild: Guild }) => { + const token = getCookie(GUILD_AUTH_COOKIE_NAME); + const userId = token && tokenSchema.parse(jwtDecode(token)).userId; + + const user = useQuery({ + queryKey: ["user", userId], + queryFn: () => fetcher(`${env.NEXT_PUBLIC_API}/user/id/${userId}`), + enabled: !!userId, + }); + + if (!user.data) { + return ; + } + + // @ts-ignore + const isJoined = !!user.data.guilds?.some( + // @ts-ignore + ({ guildId }) => guildId === guild.id, + ); + + return isJoined ? ( + + ) : (