feat: right-click context menus for channels, groups, and servers

ContextMenu: reusable hook-based component that positions a menu at
the cursor and auto-closes on outside click or Escape.

ChannelList:
- Right-click channel -> Edit Name, Permissions, Delete Channel
- Right-click group header -> Edit Name, Create Channel Here, Delete Group
- Inline rename: replacing name text with an input, commits on Enter/blur
- CreateChannelModal now accepts defaultGroupId to pre-select a group

ServerBar:
- Right-click server icon -> Server Settings, Invite People, Leave Server
- Leave calls DELETE /servers/{id}/members/me

Backend:
- Added LeaveServer handler (DELETE /servers/{serverID}/members/me)
- Server owner cannot leave; must transfer or delete
This commit is contained in:
2026-07-02 08:18:12 -04:00
parent ecb26cb731
commit 31cb295a24
6 changed files with 335 additions and 97 deletions
+3 -2
View File
@@ -4,6 +4,7 @@ import { useChannelStore } from '../stores/channel.ts';
interface CreateChannelModalProps {
serverId: string;
defaultGroupId?: string | null;
onClose: () => void;
}
@@ -36,13 +37,13 @@ const SLOWMODE_OPTIONS = [
{ label: '5 minutes', value: 300 },
];
export function CreateChannelModal({ serverId, onClose }: CreateChannelModalProps) {
export function CreateChannelModal({ serverId, defaultGroupId, onClose }: CreateChannelModalProps) {
const [name, setName] = useState('');
const [type, setType] = useState<'text' | 'voice' | 'forum' | 'calendar' | 'docs' | 'list'>('text');
const [category, setCategory] = useState('general');
const [slowmodeSeconds, setSlowmodeSeconds] = useState(0);
const [groups, setGroups] = useState<ServerGroup[]>([]);
const [selectedGroupId, setSelectedGroupId] = useState('');
const [selectedGroupId, setSelectedGroupId] = useState(defaultGroupId || '');
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);