2023-10-15 20:29:24 -07:00
|
|
|
import { ChannelType, MemberRole } from "@prisma/client";
|
2023-10-11 00:12:02 -07:00
|
|
|
import { redirect } from "next/navigation";
|
2023-10-15 20:29:24 -07:00
|
|
|
import { Hash, Mic, ShieldAlert, ShieldCheck, Video } from "lucide-react";
|
2023-10-11 00:12:02 -07:00
|
|
|
|
|
|
|
import { currentProfile } from "@/lib/current-profile";
|
|
|
|
import { db } from "@/lib/db";
|
|
|
|
|
2023-10-15 20:29:24 -07:00
|
|
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
2023-10-11 00:12:02 -07:00
|
|
|
import { SeverHeader } from "./server-header";
|
2023-10-15 20:29:24 -07:00
|
|
|
import { ServerSearch } from "./server-search";
|
|
|
|
|
2023-10-11 00:12:02 -07:00
|
|
|
|
|
|
|
interface ServerSidebarProps {
|
|
|
|
serverId: string;
|
|
|
|
}
|
|
|
|
|
2023-10-15 20:29:24 -07:00
|
|
|
const iconMap = {
|
|
|
|
[ChannelType.TEXT]: <Hash className="mr-2 h-4 w-4" />,
|
|
|
|
[ChannelType.AUDIO]: <Mic className="mr-2 h-4 w-4" />,
|
|
|
|
[ChannelType.VIDEO]: <Video className="mr-2 h-4 w-4" />
|
|
|
|
}
|
|
|
|
|
|
|
|
const roleIconMap = {
|
|
|
|
[MemberRole.GUEST]: null,
|
|
|
|
[MemberRole.MODERATOR]: <ShieldCheck className="h-4 w-4 mr-2 text-indigo-500" />,
|
|
|
|
[MemberRole.ADMIN]: <ShieldAlert className="w-4 h-4 mr-2 text-rose-500" />
|
|
|
|
}
|
|
|
|
|
2023-10-11 00:12:02 -07:00
|
|
|
export const ServerSidebar = async ({
|
|
|
|
serverId
|
|
|
|
}: ServerSidebarProps) => {
|
|
|
|
const profile = await currentProfile();
|
|
|
|
|
|
|
|
if (!profile) {
|
|
|
|
return redirect("/");
|
|
|
|
}
|
|
|
|
|
|
|
|
const server = await db.server.findUnique({
|
|
|
|
where: {
|
|
|
|
id: serverId,
|
|
|
|
},
|
|
|
|
include: {
|
|
|
|
channels: {
|
|
|
|
orderBy: {
|
|
|
|
createdAt: "asc",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
members: {
|
|
|
|
include: {
|
|
|
|
profile: true,
|
|
|
|
},
|
|
|
|
orderBy: {
|
|
|
|
role: "asc",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const textChannels = server?.channels.filter((channel) => channel.type === ChannelType.TEXT)
|
|
|
|
const audioChannels = server?.channels.filter((channel) => channel.type === ChannelType.AUDIO)
|
|
|
|
const videoChannels = server?.channels.filter((channel) => channel.type === ChannelType.VIDEO)
|
|
|
|
const members = server?.members.filter((member) => member.profileId !== profile.id)
|
|
|
|
|
|
|
|
if (!server) {
|
|
|
|
return redirect("/");
|
|
|
|
}
|
|
|
|
|
|
|
|
const role = server.members.find((member) => member.profileId === profile.id)?.role;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="flex flex-col h-full text-primary w-full dark:bg-[#2B2D31] bg-[#F2F3F5]">
|
|
|
|
<SeverHeader
|
|
|
|
server={server}
|
|
|
|
role={role}
|
|
|
|
/>
|
2023-10-15 20:29:24 -07:00
|
|
|
<ScrollArea className="flex-1 px-3">
|
|
|
|
<div className="mt-2">
|
|
|
|
<ServerSearch
|
|
|
|
data={[
|
|
|
|
{
|
|
|
|
label: "Text Channels",
|
|
|
|
type: "channel",
|
|
|
|
data: textChannels?.map((channel) => ({
|
|
|
|
id: channel.id,
|
|
|
|
name: channel.name,
|
|
|
|
icon: iconMap[channel.type],
|
|
|
|
}))
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: "Voice Channels",
|
|
|
|
type: "channel",
|
|
|
|
data: audioChannels?.map((channel) => ({
|
|
|
|
id: channel.id,
|
|
|
|
name: channel.name,
|
|
|
|
icon: iconMap[channel.type],
|
|
|
|
}))
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: "Video Channels",
|
|
|
|
type: "channel",
|
|
|
|
data: videoChannels?.map((channel) => ({
|
|
|
|
id: channel.id,
|
|
|
|
name: channel.name,
|
|
|
|
icon: iconMap[channel.type],
|
|
|
|
}))
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: "Members",
|
|
|
|
type: "member",
|
|
|
|
data: members?.map((member) => ({
|
|
|
|
id: member.id,
|
|
|
|
name: member.profile.name,
|
|
|
|
icon: roleIconMap[member.role],
|
|
|
|
}))
|
|
|
|
},
|
|
|
|
]}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</ScrollArea>
|
2023-10-11 00:12:02 -07:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|