diff --git a/app/admin/form/[id]/result/[submissionId]/client.tsx b/app/admin/form/[id]/result/[submissionId]/client.tsx index 784d9e7..81a3ba1 100644 --- a/app/admin/form/[id]/result/[submissionId]/client.tsx +++ b/app/admin/form/[id]/result/[submissionId]/client.tsx @@ -49,7 +49,7 @@ import { import { DiscordProfileDropdown, type DiscordMemberProfile, -} from "@/components/dropdown-menu-avatar"; +} from "@/components/avatar"; import { SaveStatusIndicator } from "@/components/save-status-indicator"; interface Question { diff --git a/app/admin/form/[id]/sidebar-client.tsx b/app/admin/form/[id]/sidebar-client.tsx index 8e517f7..bb66736 100644 --- a/app/admin/form/[id]/sidebar-client.tsx +++ b/app/admin/form/[id]/sidebar-client.tsx @@ -35,7 +35,7 @@ import { ThemeToggle } from "@/components/theme-toggle"; import { DropdownMenuAvatar, type DiscordMemberProfile, -} from "@/components/dropdown-menu-avatar"; +} from "@/components/avatar"; import { GuardedLink } from "@/components/guarded-link"; import { Badge } from "@/components/ui/badge"; import { cn } from "@/lib/utils"; diff --git a/app/form/client.tsx b/app/form/client.tsx index 18bca8e..87e1d08 100644 --- a/app/form/client.tsx +++ b/app/form/client.tsx @@ -43,7 +43,7 @@ import { FormItem, FormMessage, } from "@/components/ui/form"; -import { DropdownMenuAvatar, DiscordMemberProfile } from "@/components/dropdown-menu-avatar"; +import { DropdownMenuAvatar, DiscordMemberProfile } from "@/components/avatar"; import { getErrorMessage } from "@/lib/utils"; import { Accordion, diff --git a/app/profile/content.tsx b/app/profile/content.tsx index ebccf4b..65d216e 100644 --- a/app/profile/content.tsx +++ b/app/profile/content.tsx @@ -5,8 +5,7 @@ import type { LevelProgress } from "@/lib/leaderboard/level-progress"; import { formatInteger, formatVoiceDuration } from "@/lib/leaderboard/ranking"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Badge } from "@/components/ui/badge"; -import { DiscordAvatar } from "@/components/discord-avatar"; -import { DiscordServerTag } from "@/components/discord-server-tag"; +import { DiscordAvatar, DiscordServerTag } from "@/components/avatar"; import { Card, CardContent, diff --git a/components/admin-shell.tsx b/components/admin-shell.tsx index 41995e3..3e8c852 100644 --- a/components/admin-shell.tsx +++ b/components/admin-shell.tsx @@ -17,7 +17,7 @@ import { } from "@/components/ui/sidebar"; import { ClipboardList, KeyRound, Server, LayoutDashboard, Upload, LucideIcon } from "lucide-react"; import { ThemeToggle } from "@/components/theme-toggle"; -import { DropdownMenuAvatar, DiscordMemberProfile } from "@/components/dropdown-menu-avatar"; +import { DropdownMenuAvatar, DiscordMemberProfile } from "@/components/avatar"; interface NavItem { href: string; diff --git a/components/dropdown-menu-avatar.tsx b/components/avatar.tsx similarity index 78% rename from components/dropdown-menu-avatar.tsx rename to components/avatar.tsx index 86328cf..e708135 100644 --- a/components/dropdown-menu-avatar.tsx +++ b/components/avatar.tsx @@ -3,6 +3,7 @@ import { useState, type ReactNode } from "react"; import { usePathname } from "next/navigation"; import Link from "next/link"; +import Image from "next/image"; import { LogOut, UserRound } from "lucide-react"; import { signOut } from "next-auth/react"; import { @@ -14,8 +15,12 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Button } from "@/components/ui/button"; -import { DiscordAvatar } from "@/components/discord-avatar"; -import { DiscordServerTag } from "@/components/discord-server-tag"; +import { + Avatar, + AvatarFallback, + AvatarImage, +} from "@/components/ui/avatar"; +import { Badge } from "@/components/ui/badge"; import type { DiscordMemberProfile as DiscordMemberProfileData, DiscordRole, @@ -23,11 +28,79 @@ import type { import { discordColorToHex, } from "@/lib/discord/profile-appearance"; +import { cn } from "@/lib/utils"; export type DiscordMemberProfile = DiscordMemberProfileData; const DEFAULT_ROLE_COLOR = "#99aab5"; +type DiscordAvatarProps = { + avatarUrl: string | null; + decorationUrl?: string | null; + alt: string; + fallback: string; + className?: string; + imageError?: boolean; + onImageError?: () => void; +}; + +export function DiscordAvatar({ + avatarUrl, + decorationUrl, + alt, + fallback, + className, + imageError = false, + onImageError, +}: DiscordAvatarProps) { + return ( +