From 8ab022eabee684b14962320925a4f27fff0fc14c Mon Sep 17 00:00:00 2001 From: Chneemann Date: Fri, 18 Sep 2026 04:27:20 +0200 Subject: [PATCH] feat(members): update roleEnum to support OWNER, MODERATOR, MEMBER, and GUEST --- components/members/MemberItem.tsx | 45 ++++++++++++++++--------------- components/members/MemberList.tsx | 8 ++---- db/schema.ts | 9 +++++-- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/components/members/MemberItem.tsx b/components/members/MemberItem.tsx index 9e9bc55..ce00a07 100644 --- a/components/members/MemberItem.tsx +++ b/components/members/MemberItem.tsx @@ -5,7 +5,7 @@ "use client"; -import { useState, useRef, useEffect } from "react"; +import { useState, useRef, useEffect, ReactNode } from "react"; import { useRouter } from "next/navigation"; import { clsx } from "clsx"; import { UserAvatar } from "../ui/UserAvatar"; @@ -16,16 +16,11 @@ import { } from "@/lib/context/ServerContext"; import { useSidebarStore } from "@/lib/stores/useSidebarStore"; import { useUser } from "@/lib/context/UserContext"; -import { Crown, Shield } from "lucide-react"; - -/** Props for the MemberItem component. */ -interface MemberItemProps { - member: ServerMemberWithUser; - isOffline?: boolean; -} +import { Crown, ShieldCheck } from "lucide-react"; +import { Member } from "@/db/schema"; /** Renders an individual member item with an interactive user profile popover and role badge. */ -export function MemberItem({ member, isOffline = false }: MemberItemProps) { +export function MemberItem({ member }: { member: ServerMemberWithUser }) { const router = useRouter(); const { setActiveServer } = useActiveServer(); const { closeMembers } = useSidebarStore(); @@ -37,7 +32,13 @@ export function MemberItem({ member, isOffline = false }: MemberItemProps) { const containerRef = useRef(null); const triggerRef = useRef(null); - // Close popover on click outside or ESC key press + /** Map of server member roles to their corresponding icon elements. */ + const ROLE_ICONS: Partial> = { + OWNER: , + MODERATOR: , + }; + + /** Closes popover on click outside or ESC key press. */ useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( @@ -125,26 +126,26 @@ export function MemberItem({ member, isOffline = false }: MemberItemProps) { onClick={() => setIsProfileOpen((prev) => !prev)} className={clsx( "w-full flex items-center justify-between px-2 py-1.5 rounded-md hover:bg-background/50 transition-colors cursor-pointer group text-left focus:outline-none", - isOffline && "opacity-60", + member.status == "OFFLINE" && "opacity-50", )} >
- - {member.username} - +
+

+ {member.username} +

+

+ {member.role.toLowerCase()} +

+
- {/* Rolle-Badge/Icon */} -
- {member.role === "OWNER" && ( - - )} - {member.role === "ADMIN" && ( - - )} + {/* Role Badges & Icons */} +
+ {ROLE_ICONS[member.role]}
diff --git a/components/members/MemberList.tsx b/components/members/MemberList.tsx index ce5ceb7..a40800d 100644 --- a/components/members/MemberList.tsx +++ b/components/members/MemberList.tsx @@ -8,11 +8,7 @@ import { MemberItem } from "@/components/members/MemberItem"; import { ServerMemberWithUser } from "@/lib/context/ServerContext"; /** Renders online and offline community members in distinct sections. */ -export function MemberList({ - members = [], -}: { - members?: ServerMemberWithUser[]; -}) { +export function MemberList({ members }: { members: ServerMemberWithUser[] }) { const { onlineMembers, offlineMembers } = useMemo(() => { return { onlineMembers: members.filter((m) => m.status !== "OFFLINE"), @@ -46,7 +42,7 @@ export function MemberList({
{offlineMembers.map((member) => ( - + ))}
diff --git a/db/schema.ts b/db/schema.ts index becde63..d3d4769 100644 --- a/db/schema.ts +++ b/db/schema.ts @@ -19,7 +19,12 @@ import { // ========================================== /** Enum representing member access roles within a server. */ -export const roleEnum = pgEnum("role", ["OWNER", "ADMIN", "MEMBER"]); +export const roleEnum = pgEnum("role", [ + "OWNER", + "MODERATOR", + "MEMBER", + "GUEST", +]); /** Enum representing online status of a user. */ export const userStatusEnum = pgEnum("user_status", [ @@ -67,7 +72,7 @@ export const servers = pgTable("servers", { /** Database table definition linking users to servers with specific roles. */ export const members = pgTable("members", { id: uuid("id").primaryKey().defaultRandom(), - role: roleEnum("role").default("MEMBER").notNull(), + role: roleEnum("role").default("GUEST").notNull(), userId: uuid("user_id") .references(() => users.id, { onDelete: "cascade" }) .notNull(),