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

add open graph stuff to team

+67 -10
+48 -1
app/(home)/team/page.tsx
··· 1 import Image from "next/image"; 2 import Link from "next/link"; 3 import { HiExternalLink } from "react-icons/hi"; 4 5 import { getUser } from "@/lib/discord/user"; 6 import { filterDuplicates } from "@/lib/filter-duplicates"; 7 import cn from "@/utils/cn"; 8 9 enum TeamType { 10 Developer = "developer", ··· 77 } 78 ] as const; 79 80 export default function Home() { 81 return ( 82 <div> 83 <h2 className="text-2xl font-medium text-neutral-200">Team 🍪</h2> 84 85 - <div className="divide-y-1 divide-wamellow"> 86 {filterDuplicates(data.map((person) => person.team)).map((team) => ( 87 <div 88 key={team} ··· 116 </div> 117 </div> 118 ))} 119 </div> 120 121 </div>
··· 1 + import { Metadata } from "next"; 2 import Image from "next/image"; 3 import Link from "next/link"; 4 import { HiExternalLink } from "react-icons/hi"; 5 6 import { getUser } from "@/lib/discord/user"; 7 import { filterDuplicates } from "@/lib/filter-duplicates"; 8 + import MommyPic from "@/public/mommy.webp"; 9 import cn from "@/utils/cn"; 10 + import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 11 12 enum TeamType { 13 Developer = "developer", ··· 80 } 81 ] as const; 82 83 + export const generateMetadata = async (): Promise<Metadata> => { 84 + const title = "Team"; 85 + const description = "Meet the creators of Wamellow and its products. Our dedicated team, including developers and donors, drives innovation and community growth."; 86 + const url = getCanonicalUrl("team"); 87 + 88 + return { 89 + title, 90 + description, 91 + alternates: { 92 + canonical: url 93 + }, 94 + openGraph: { 95 + title, 96 + description, 97 + url, 98 + type: "website", 99 + images: { 100 + url: `${getBaseUrl()}/mommy.webp`, 101 + type: "image/webp" 102 + } 103 + }, 104 + twitter: { 105 + card: "summary", 106 + title, 107 + description, 108 + images: { 109 + url: `${getBaseUrl()}/mommy.webp`, 110 + alt: title 111 + } 112 + } 113 + }; 114 + }; 115 + 116 export default function Home() { 117 return ( 118 <div> 119 <h2 className="text-2xl font-medium text-neutral-200">Team 🍪</h2> 120 + <div className="max-w-xl"> 121 + Meet the creators of Wamellow and its products. Our dedicated team, including developers and donors, drives innovation and community growth 122 + </div> 123 124 + <div className="relative divide-y-1 divide-wamellow"> 125 {filterDuplicates(data.map((person) => person.team)).map((team) => ( 126 <div 127 key={team} ··· 155 </div> 156 </div> 157 ))} 158 + 159 + <Image 160 + alt="no mommy? 😢" 161 + className="absolute right-0 top-0 shrink-0 aspect-square rounded-lg" 162 + height={128} 163 + src={MommyPic} 164 + width={128} 165 + /> 166 </div> 167 168 </div>
+16 -8
components/footer.tsx
··· 1 import Image from "next/image"; 2 import Link from "next/link"; 3 import { HTMLProps } from "react"; ··· 7 import { SiKofi } from "react-icons/si"; 8 9 import TopggIcon from "@/components/icons/topgg"; 10 import BlahajPic from "@/public/blahaj.webp"; 11 - import LunaPic from "@/public/luna.webp"; 12 import cn from "@/utils/cn"; 13 14 - export default function Footer(props: HTMLProps<HTMLDivElement>) { 15 return ( 16 <div 17 className={cn("text-neutral-500 w-full mt-10 text-left", props.className)} ··· 37 </span> 38 <span className="flex gap-1 items-center"> 39 <HiCube /> 40 - <span className="flex gap-0.5 items-center"> 41 - {/* Version {version.toString().slice(0, 7)} by */} 42 - <span> 43 - Made by <Link className="hover:underline" href="/support" aria-label="lunish.nl developer">Luna</Link> 44 - </span> 45 - <Image src={LunaPic} alt="mwlica" width={16} height={16} className="h-4 w-4 rounded-full ml-0.5" /> 46 </span> 47 </span> 48 </div>
··· 1 + import { Chip } from "@nextui-org/react"; 2 import Image from "next/image"; 3 import Link from "next/link"; 4 import { HTMLProps } from "react"; ··· 8 import { SiKofi } from "react-icons/si"; 9 10 import TopggIcon from "@/components/icons/topgg"; 11 + import { getUser } from "@/lib/discord/user"; 12 import BlahajPic from "@/public/blahaj.webp"; 13 import cn from "@/utils/cn"; 14 15 + export default async function Footer(props: HTMLProps<HTMLDivElement>) { 16 + 17 + const dev = await getUser("821472922140803112"); 18 + 19 return ( 20 <div 21 className={cn("text-neutral-500 w-full mt-10 text-left", props.className)} ··· 41 </span> 42 <span className="flex gap-1 items-center"> 43 <HiCube /> 44 + <span className="flex items-center"> 45 + Made by 46 + <Chip 47 + className="relative top-0.5 ml-0.5" 48 + as={Link} 49 + href="/team" 50 + startContent={<Image src={dev?.avatarUrl as string} alt="Luna" width={18} height={18} className="rounded-full" />} 51 + > 52 + {dev?.username} 53 + </Chip> 54 </span> 55 </span> 56 </div>
+3 -1
lib/discord/user.ts
··· 1 import { Collection } from "@discordjs/collection"; 2 import { APIUser, RESTGetAPIUserResult, Routes } from "discord-api-types/v10"; 3 4 - import { rest } from "."; 5 6 const cache = new Collection<string, User>(); 7 ··· 11 this.username = data.username; 12 this.globalName = data.global_name || null; 13 this.avatar = data.avatar; 14 this.bot = data.bot || false; 15 } 16 ··· 18 public username: string; 19 public globalName: string | null; 20 public avatar: string | null; 21 public bot: boolean; 22 } 23
··· 1 import { Collection } from "@discordjs/collection"; 2 import { APIUser, RESTGetAPIUserResult, Routes } from "discord-api-types/v10"; 3 4 + import { rest } from "./index"; 5 6 const cache = new Collection<string, User>(); 7 ··· 11 this.username = data.username; 12 this.globalName = data.global_name || null; 13 this.avatar = data.avatar; 14 + this.avatarUrl = data.avatar ? `https://cdn.discordapp.com/avatars/${data.id}/${data.avatar}.${data.avatar.startsWith("a_") ? "gif" : "webp"}` : null; 15 this.bot = data.bot || false; 16 } 17 ··· 19 public username: string; 20 public globalName: string | null; 21 public avatar: string | null; 22 + public avatarUrl: string | null; 23 public bot: boolean; 24 } 25
public/mommy.webp

This is a binary file and will not be displayed.