refactor(ui): move category creation from ChannelSidebar to ServerSettingsMenu
All checks were successful
Deploy Waveform to VPS / deploy (push) Successful in 3m24s
All checks were successful
Deploy Waveform to VPS / deploy (push) Successful in 3m24s
This commit is contained in:
parent
c6af4e1565
commit
4622dac9bf
2 changed files with 88 additions and 33 deletions
|
|
@ -1,57 +1,119 @@
|
|||
/**
|
||||
* @file components/layout/ServerSettingsMenu.tsx
|
||||
* @description Header button triggering the server overview/settings modal.
|
||||
* @description Single settings dropdown menu providing server management actions (Settings, Create Category, Create Channel).
|
||||
*/
|
||||
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Settings } from "lucide-react";
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { Settings, FolderPlus, PlusCircle, Sliders } from "lucide-react";
|
||||
import { EditServerModal } from "@/components/modals/EditServerModal";
|
||||
import { CreateCategoryModal } from "@/components/modals/CreateCategoryModal";
|
||||
import { CreateChannelModal } from "@/components/modals/CreateChannelModal";
|
||||
|
||||
/**
|
||||
* Props for the ServerSettingsMenu component.
|
||||
*
|
||||
* @interface ServerSettingsMenuProps
|
||||
* @property {string} serverId - The unique identifier of the server.
|
||||
* @property {string} serverName - The display name of the server.
|
||||
*/
|
||||
/** Props for the ServerSettingsMenu component. */
|
||||
interface ServerSettingsMenuProps {
|
||||
serverId: string;
|
||||
serverName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a settings button that opens the edit server modal.
|
||||
*
|
||||
* @param {ServerSettingsMenuProps} props - The component props.
|
||||
* @param {string} props.serverId - The unique identifier of the server.
|
||||
* @param {string} props.serverName - The display name of the server.
|
||||
* @returns {JSX.Element} The rendered server settings trigger and modal component.
|
||||
*/
|
||||
/** Renders a server management dropdown menu with modal triggers for channel, category, and server settings. */
|
||||
export function ServerSettingsMenu({
|
||||
serverId,
|
||||
serverName,
|
||||
}: ServerSettingsMenuProps) {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
const [isEditServerOpen, setIsEditServerOpen] = useState(false);
|
||||
const [isCreateCategoryOpen, setIsCreateCategoryOpen] = useState(false);
|
||||
const [isCreateChannelOpen, setIsCreateChannelOpen] = useState(false);
|
||||
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Close the menu when clicked outside of it
|
||||
useEffect(() => {
|
||||
function handleClickOutside(event: MouseEvent) {
|
||||
if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
|
||||
setIsMenuOpen(false);
|
||||
}
|
||||
}
|
||||
if (isMenuOpen) {
|
||||
document.addEventListener("mousedown", handleClickOutside);
|
||||
}
|
||||
return () => document.removeEventListener("mousedown", handleClickOutside);
|
||||
}, [isMenuOpen]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="relative" ref={menuRef}>
|
||||
{/* Button */}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
title="Server Settings"
|
||||
onClick={() => setIsMenuOpen((prev) => !prev)}
|
||||
title="Server-Optionen"
|
||||
className="p-1.5 rounded-md text-muted hover:text-white hover:bg-surface transition-colors cursor-pointer"
|
||||
>
|
||||
<Settings className="w-5 h-5" />
|
||||
</button>
|
||||
|
||||
{/* Dropdown Menü */}
|
||||
{isMenuOpen && (
|
||||
<div className="absolute right-0 mt-2 w-52 bg-surface border border-background rounded-lg shadow-lg py-1 z-50 animate-in fade-in zoom-in-95 duration-100">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setIsMenuOpen(false);
|
||||
setIsCreateChannelOpen(true);
|
||||
}}
|
||||
className="w-full flex items-center gap-2 px-3 py-2 text-sm text-muted hover:text-white hover:bg-background transition-colors text-left cursor-pointer"
|
||||
>
|
||||
<PlusCircle className="w-4 h-4" />
|
||||
<span>Kanal erstellen</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setIsMenuOpen(false);
|
||||
setIsCreateCategoryOpen(true);
|
||||
}}
|
||||
className="w-full flex items-center gap-2 px-3 py-2 text-sm text-muted hover:text-white hover:bg-background transition-colors text-left cursor-pointer"
|
||||
>
|
||||
<FolderPlus className="w-4 h-4" />
|
||||
<span>Kategorie erstellen</span>
|
||||
</button>
|
||||
|
||||
<div className="my-1 border-t border-background" />
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setIsMenuOpen(false);
|
||||
setIsEditServerOpen(true);
|
||||
}}
|
||||
className="w-full flex items-center gap-2 px-3 py-2 text-sm text-muted hover:text-white hover:bg-background transition-colors text-left cursor-pointer"
|
||||
>
|
||||
<Sliders className="w-4 h-4" />
|
||||
<span>Servereinstellungen</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Modals */}
|
||||
<EditServerModal
|
||||
isOpen={isModalOpen}
|
||||
isOpen={isEditServerOpen}
|
||||
serverId={serverId}
|
||||
initialName={serverName}
|
||||
onClose={() => setIsModalOpen(false)}
|
||||
onClose={() => setIsEditServerOpen(false)}
|
||||
/>
|
||||
</>
|
||||
<CreateCategoryModal
|
||||
isOpen={isCreateCategoryOpen}
|
||||
onClose={() => setIsCreateCategoryOpen(false)}
|
||||
serverId={serverId}
|
||||
/>
|
||||
<CreateChannelModal
|
||||
isOpen={isCreateChannelOpen}
|
||||
onClose={() => setIsCreateChannelOpen(false)}
|
||||
serverId={serverId}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { CreateCategoryModal } from "@/components/modals/CreateCategoryModal";
|
|||
import { EditChannelModal } from "@/components/modals/EditChannelModal";
|
||||
import { EditCategoryModal } from "@/components/modals/EditCategoryModal";
|
||||
import { CategorySection } from "./CategorySection";
|
||||
import { FolderPlus, PanelLeftClose } from "lucide-react";
|
||||
import { PanelLeftClose } from "lucide-react";
|
||||
import type { Category, Channel } from "@/db/schema";
|
||||
|
||||
/** Renders the channel sidebar navigation for the active server. */
|
||||
|
|
@ -55,13 +55,6 @@ export function ChannelSidebar() {
|
|||
<div className="h-14 border-b border-background flex items-center justify-between px-4 font-bold text-white shadow-sm shrink-0">
|
||||
<span className="truncate">{activeServer.name}</span>
|
||||
<div className="flex items-center gap-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIsCreateCategoryOpen(true)}
|
||||
className="p-1.5 rounded-md text-muted hover:text-white hover:bg-surface transition-colors cursor-pointer shrink-0"
|
||||
>
|
||||
<FolderPlus className="w-4 h-4" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={toggleNav}
|
||||
|
|
|
|||
Loading…
Reference in a new issue