The weeb for the next gen discord boat - Wamellow wamellow.com
bot discord
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

use react query on profiles and add votes

Luna f1161aac 9fdd3369

+51 -51
+49 -51
app/profile/layout.tsx
··· 1 1 "use client"; 2 2 3 - import { Skeleton } from "@nextui-org/react"; 3 + import { Chip, Skeleton } from "@nextui-org/react"; 4 4 import Image from "next/image"; 5 - import { Suspense, useEffect, useState } from "react"; 5 + import Link from "next/link"; 6 + import { Suspense } from "react"; 6 7 import CountUp from "react-countup"; 7 - import { HiChartPie, HiHome, HiMusicNote, HiPhotograph, HiTranslate } from "react-icons/hi"; 8 + import { HiChartPie, HiFire, HiHome, HiMusicNote, HiPhotograph, HiTranslate } from "react-icons/hi"; 9 + import { useQuery } from "react-query"; 8 10 9 11 import { userStore } from "@/common/user"; 10 12 import ImageReduceMotion from "@/components/image-reduce-motion"; 11 13 import { ListTab } from "@/components/list"; 12 14 import { HomeButton, ScreenMessage, SupportButton } from "@/components/screen-message"; 15 + import { getData } from "@/lib/api"; 13 16 import SadWumpusPic from "@/public/sad-wumpus.gif"; 14 - import { ApiV1MeGetResponse, RouteErrorResponse } from "@/typings"; 17 + import { ApiV1MeGetResponse } from "@/typings"; 15 18 import decimalToRgb from "@/utils/decimalToRgb"; 16 19 17 20 export default function RootLayout({ ··· 20 23 children: React.ReactNode 21 24 }) { 22 25 const user = userStore((g) => g); 23 - 24 - const [error, setError] = useState<string>(); 25 - 26 26 const accent = decimalToRgb(user?.accent_color as number); 27 27 28 - useEffect(() => { 29 - if (user?.extended !== undefined) return; 30 - 31 - fetch(`${process.env.NEXT_PUBLIC_API}/users/@me`, { 32 - headers: { 33 - authorization: localStorage.getItem("token") as string 34 - } 35 - }) 36 - .then(async (res) => { 37 - const response = await res.json() as ApiV1MeGetResponse; 38 - if (!response) return; 28 + const url = "/users/@me" as const; 39 29 40 - switch (res.status) { 41 - case 200: { 42 - setError(undefined); 43 - userStore.setState({ ...user, extended: response }); 44 - break; 45 - } 46 - default: { 47 - setError((response as unknown as RouteErrorResponse).message); 48 - break; 49 - } 50 - } 30 + const { status } = useQuery( 31 + ["users", "@me"], 32 + () => getData<ApiV1MeGetResponse>(url), 33 + { 34 + enabled: !!user?.id, 35 + onSuccess: (d) => userStore.setState({ ...user, extended: d }) 36 + } 37 + ); 51 38 52 - }) 53 - .catch(() => { 54 - setError("Error while fetching user"); 55 - }); 56 - }, [user]); 39 + if (status === "error") { 40 + return ( 41 + <ScreenMessage 42 + top="0rem" 43 + title="Something went wrong on this page.." 44 + description="An unknown error occurred." 45 + buttons={<> 46 + <HomeButton /> 47 + <SupportButton /> 48 + </>} 49 + > 50 + <Image src={SadWumpusPic} alt="" height={141} width={124} /> 51 + </ScreenMessage> 52 + ); 53 + } 57 54 58 55 return ( 59 56 <div className="flex flex-col w-full h-full"> ··· 63 60 64 61 <div className="text-lg flex flex-col md:flex-row md:items-center"> 65 62 <div className="flex gap-5"> 66 - <Skeleton isLoaded={!!user?.id} className="rounded-full h-14 w-14 ring-offset-[var(--background-rgb)] ring-2 ring-offset-2 ring-violet-400/40 shrink-0" style={user?.accent_color ? { "--tw-ring-color": `rgb(${accent.r}, ${accent.g}, ${accent.b})` } as React.CSSProperties : {}}> 63 + <Skeleton 64 + isLoaded={!!user?.id} 65 + className="rounded-full h-14 w-14 ring-offset-[var(--background-rgb)] ring-2 ring-offset-2 ring-violet-400/40 shrink-0 relative top-1" 66 + style={user?.accent_color ? { "--tw-ring-color": `rgb(${accent.r}, ${accent.g}, ${accent.b})` } as React.CSSProperties : {}} 67 + > 67 68 <ImageReduceMotion url={`https://cdn.discordapp.com/avatars/${user?.id}/${user?.avatar}`} size={128} alt="you" /> 68 69 </Skeleton> 69 70 ··· 75 76 : 76 77 <div className="flex flex-col gap-1"> 77 78 <div className="text-2xl dark:text-neutral-200 text-neutral-800 font-medium">@{user?.username || "Unknown User"}</div> 78 - <div className="text-sm font-semibold flex items-center gap-1"> Manage your profile here </div> 79 + <Chip 80 + as={Link} 81 + href="/vote" 82 + target="_blank" 83 + color="secondary" 84 + startContent={<HiFire className="ml-1" />} 85 + variant="flat" 86 + radius="sm" 87 + > 88 + <span className="font-bold uppercase"> {user.extended?.voteCount} votes </span> 89 + </Chip> 79 90 </div> 80 91 } 81 92 </div> ··· 145 156 ) 146 157 ]} 147 158 url={"/profile"} 148 - disabled={!user?.id || !!error} 159 + disabled={!user?.id} 149 160 /> 150 161 </Suspense> 151 162 152 - {error ? 153 - <ScreenMessage 154 - title="Something went wrong on this page.." 155 - description={error} 156 - buttons={<> 157 - <HomeButton /> 158 - <SupportButton /> 159 - </>} 160 - > 161 - <Image src={SadWumpusPic} alt="" height={141} width={124} /> 162 - </ScreenMessage> 163 - : 164 - user?.id ? children : <></> 165 - } 163 + {user?.id ? children : <></>} 166 164 167 165 </div> 168 166 );
+2
typings.ts
··· 268 268 | "en_female_f08_salut_damour" | "en_male_m03_lobby" | "en_male_m03_sunshine_soon" | "en_female_f08_warmy_breeze" | "en_female_ht_f08_glorious" | "en_male_sing_funny_it_goes_up" | "en_male_m2_xhxs_m03_silly" | "en_female_ht_f08_wonderful_world" 269 269 270 270 export interface ApiV1MeGetResponse { 271 + voteCount?: number; 272 + 271 273 rank?: { 272 274 background?: string | null; 273 275 textColor?: number;