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 ( +
+ + {!imageError && avatarUrl && ( + + )} + {fallback} + + {decorationUrl && ( + + )} +
+ ); +} + +export function DiscordServerTag({ + primaryGuild, +}: Pick) { + if (!primaryGuild) return null; + + return ( + + {primaryGuild.badgeUrl && ( + + )} + {primaryGuild.tag} + + ); +} + function initials(value: string) { return value.trim().slice(0, 2).toLocaleUpperCase("th-TH") || "?"; } diff --git a/components/discord-avatar.tsx b/components/discord-avatar.tsx deleted file mode 100644 index bb86aeb..0000000 --- a/components/discord-avatar.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import Image from "next/image"; -import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; -import { cn } from "@/lib/utils"; - -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 ( -
- - {!imageError && avatarUrl && ( - - )} - {fallback} - - {decorationUrl && ( - - )} -
- ); -} diff --git a/components/discord-server-tag.tsx b/components/discord-server-tag.tsx deleted file mode 100644 index c46b4bc..0000000 --- a/components/discord-server-tag.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import Image from "next/image"; -import { Badge } from "@/components/ui/badge"; -import type { DiscordMemberProfile } from "@/lib/discord/discord"; - -export function DiscordServerTag({ - primaryGuild, -}: Pick) { - if (!primaryGuild) return null; - - return ( - - {primaryGuild.badgeUrl && ( - - )} - {primaryGuild.tag} - - ); -}