created server sidebar header and dropdown menu
This commit is contained in:
parent
65d90df42a
commit
868021049c
51
app/(main)/(routes)/servers/[serverId]/layout.tsx
Normal file
51
app/(main)/(routes)/servers/[serverId]/layout.tsx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
|
||||||
|
import { redirectToSignIn } from "@clerk/nextjs";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
|
import { currentProfile } from "@/lib/current-profile";
|
||||||
|
import { db } from "@/lib/db";
|
||||||
|
|
||||||
|
import { ServerSidebar } from "@/components/server/server-sidebar";
|
||||||
|
|
||||||
|
const ServerIdLayout = async ({
|
||||||
|
children,
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
params: { serverId: string};
|
||||||
|
}) => {
|
||||||
|
const profile = await currentProfile();
|
||||||
|
|
||||||
|
if (!profile) {
|
||||||
|
return redirectToSignIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
const server = await db.server.findUnique({
|
||||||
|
where: {
|
||||||
|
id: params.serverId,
|
||||||
|
members: {
|
||||||
|
some: {
|
||||||
|
profileId: profile.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!server) {
|
||||||
|
return redirect("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="h-full">
|
||||||
|
<div
|
||||||
|
className="hidden md:flex h-full w-60 z-20 flex-col fixed inset-y-0">
|
||||||
|
<ServerSidebar serverId={params.serverId} />
|
||||||
|
</div>
|
||||||
|
<main className="h-full md:pl-60">
|
||||||
|
{children}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default ServerIdLayout;
|
85
components/server/server-header.tsx
Normal file
85
components/server/server-header.tsx
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { ServerWithMembersWithProfiles } from "@/types";
|
||||||
|
import { MemberRole } from "@prisma/client";
|
||||||
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||||
|
import { ChevronDown, LogOutIcon, Plus, PlusCircle, Settings, Trash, Users } from "lucide-react";
|
||||||
|
|
||||||
|
interface ServerHeaderProps {
|
||||||
|
server: ServerWithMembersWithProfiles;
|
||||||
|
role?: MemberRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SeverHeader = ({server, role}: ServerHeaderProps) => {
|
||||||
|
const isAdmin = role === MemberRole.ADMIN;
|
||||||
|
const isModerator = isAdmin || role === MemberRole.MODERATOR;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger
|
||||||
|
className="focus:outline-none"
|
||||||
|
asChild
|
||||||
|
>
|
||||||
|
<button className="w-full text-md font-semibold px-3 flex items-center h-12 border-neutral-2 dark:border-neutral-800 border-b-2 hover:bg-zinc-700/10 dark:hover:bg-zinc-700/50 transition"
|
||||||
|
>
|
||||||
|
{server.name}
|
||||||
|
<ChevronDown className="w-5 h-5 ml-auto"/>
|
||||||
|
</button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="w-56 text-xs font-medium text-black dark:text-neutral-400 space-y-[2px]"
|
||||||
|
>
|
||||||
|
{isModerator && (
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="text-indigo-600 dark:text-indigo-400 px-3 py-2 text-sm cursor-pointer"
|
||||||
|
>
|
||||||
|
Invite People
|
||||||
|
<Plus className="w-4 h-4 ml-auto"/>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
{isAdmin && (
|
||||||
|
<DropdownMenuItem
|
||||||
|
className=" px-3 py-2 text-sm cursor-pointer"
|
||||||
|
>
|
||||||
|
Server Settings
|
||||||
|
<Settings className="w-4 h-4 ml-auto"/>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
{isModerator && (
|
||||||
|
<DropdownMenuItem
|
||||||
|
className=" px-3 py-2 text-sm cursor-pointer"
|
||||||
|
>
|
||||||
|
Manager Members
|
||||||
|
<Users className="w-4 h-4 ml-auto"/>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
{isModerator && (
|
||||||
|
<DropdownMenuItem
|
||||||
|
className=" px-3 py-2 text-sm cursor-pointer"
|
||||||
|
>
|
||||||
|
Create Channel
|
||||||
|
<PlusCircle className="w-4 h-4 ml-auto"/>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
{isModerator && (
|
||||||
|
<DropdownMenuSeparator/>
|
||||||
|
)}
|
||||||
|
{isAdmin && (
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="text-rose-500 px-3 py-2 text-sm cursor-pointer"
|
||||||
|
>
|
||||||
|
Delete Server
|
||||||
|
<Trash className="w-4 h-4 ml-auto"/>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
{!isAdmin && (
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="text-rose-500 px-3 py-2 text-sm cursor-pointer"
|
||||||
|
>
|
||||||
|
Delete Server
|
||||||
|
<LogOutIcon className="w-4 h-4 ml-auto"/>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
)
|
||||||
|
}
|
62
components/server/server-sidebar.tsx
Normal file
62
components/server/server-sidebar.tsx
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { ChannelType } from "@prisma/client";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
|
import { currentProfile } from "@/lib/current-profile";
|
||||||
|
import { db } from "@/lib/db";
|
||||||
|
|
||||||
|
import { SeverHeader } from "./server-header";
|
||||||
|
|
||||||
|
interface ServerSidebarProps {
|
||||||
|
serverId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
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}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user