fix(bots): channel picker dropdown instead of ID text input
Server selector + channel dropdown for built-in bot config. No more asking users to paste UUIDs.
This commit is contained in:
@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { useBotStore, type Bot } from '../stores/bot.ts';
|
import { useBotStore, type Bot } from '../stores/bot.ts';
|
||||||
import { useServerStore } from '../stores/server.ts';
|
import { useServerStore } from '../stores/server.ts';
|
||||||
|
import { useChannelStore } from '../stores/channel.ts';
|
||||||
|
|
||||||
// ponytail: config fields per bot type, add new types here
|
// ponytail: config fields per bot type, add new types here
|
||||||
const BOT_TYPE_CONFIGS: Record<string, { label: string; fields: { key: string; label: string; type: 'text' | 'number' | 'channel'; placeholder: string }[] }> = {
|
const BOT_TYPE_CONFIGS: Record<string, { label: string; fields: { key: string; label: string; type: 'text' | 'number' | 'channel'; placeholder: string }[] }> = {
|
||||||
@@ -27,12 +28,15 @@ export function BotManager() {
|
|||||||
|
|
||||||
const servers = useServerStore((s) => s.servers);
|
const servers = useServerStore((s) => s.servers);
|
||||||
const fetchServers = useServerStore((s) => s.fetchServers);
|
const fetchServers = useServerStore((s) => s.fetchServers);
|
||||||
|
const channelsByServer = useChannelStore((s) => s.channelsByServer);
|
||||||
|
const fetchChannels = useChannelStore((s) => s.fetchChannels);
|
||||||
|
|
||||||
const [showCreate, setShowCreate] = useState(false);
|
const [showCreate, setShowCreate] = useState(false);
|
||||||
const [createName, setCreateName] = useState('');
|
const [createName, setCreateName] = useState('');
|
||||||
const [createDesc, setCreateDesc] = useState('');
|
const [createDesc, setCreateDesc] = useState('');
|
||||||
const [createType, setCreateType] = useState('');
|
const [createType, setCreateType] = useState('');
|
||||||
const [createConfig, setCreateConfig] = useState<Record<string, string>>({});
|
const [createConfig, setCreateConfig] = useState<Record<string, string>>({});
|
||||||
|
const [channelServerId, setChannelServerId] = useState('');
|
||||||
const [editingId, setEditingId] = useState<string | null>(null);
|
const [editingId, setEditingId] = useState<string | null>(null);
|
||||||
const [editName, setEditName] = useState('');
|
const [editName, setEditName] = useState('');
|
||||||
const [editDesc, setEditDesc] = useState('');
|
const [editDesc, setEditDesc] = useState('');
|
||||||
@@ -63,6 +67,7 @@ export function BotManager() {
|
|||||||
setCreateDesc('');
|
setCreateDesc('');
|
||||||
setCreateType('');
|
setCreateType('');
|
||||||
setCreateConfig({});
|
setCreateConfig({});
|
||||||
|
setChannelServerId('');
|
||||||
setShowCreate(false);
|
setShowCreate(false);
|
||||||
} catch {
|
} catch {
|
||||||
// error handled in store
|
// error handled in store
|
||||||
@@ -221,13 +226,35 @@ export function BotManager() {
|
|||||||
<div key={field.key}>
|
<div key={field.key}>
|
||||||
<label className="block text-gb-fg-f mb-1 font-mono text-xs">{field.label}:</label>
|
<label className="block text-gb-fg-f mb-1 font-mono text-xs">{field.label}:</label>
|
||||||
{field.type === 'channel' ? (
|
{field.type === 'channel' ? (
|
||||||
<input
|
<div className="space-y-1">
|
||||||
type="text"
|
<select
|
||||||
|
value={channelServerId}
|
||||||
|
onChange={(e) => {
|
||||||
|
setChannelServerId(e.target.value);
|
||||||
|
setCreateConfig((prev) => ({ ...prev, [field.key]: '' }));
|
||||||
|
if (e.target.value) fetchChannels(e.target.value);
|
||||||
|
}}
|
||||||
|
className="terminal-input w-full"
|
||||||
|
>
|
||||||
|
<option value="">-- select server first --</option>
|
||||||
|
{servers.map((s) => (
|
||||||
|
<option key={s.id} value={s.id}>{s.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<select
|
||||||
value={createConfig[field.key] || ''}
|
value={createConfig[field.key] || ''}
|
||||||
onChange={(e) => setCreateConfig((prev) => ({ ...prev, [field.key]: e.target.value }))}
|
onChange={(e) => setCreateConfig((prev) => ({ ...prev, [field.key]: e.target.value }))}
|
||||||
placeholder="channel ID (from URL)"
|
|
||||||
className="terminal-input w-full"
|
className="terminal-input w-full"
|
||||||
/>
|
disabled={!channelServerId}
|
||||||
|
>
|
||||||
|
<option value="">-- select channel --</option>
|
||||||
|
{(channelsByServer[channelServerId] || [])
|
||||||
|
.filter((c) => c.type === 'text')
|
||||||
|
.map((c) => (
|
||||||
|
<option key={c.id} value={c.id}>#{c.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<input
|
<input
|
||||||
type={field.type}
|
type={field.type}
|
||||||
@@ -245,7 +272,7 @@ export function BotManager() {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => { setShowCreate(false); setCreateName(''); setCreateDesc(''); setCreateType(''); setCreateConfig({}); }}
|
onClick={() => { setShowCreate(false); setCreateName(''); setCreateDesc(''); setCreateType(''); setCreateConfig({}); setChannelServerId(''); }}
|
||||||
className="text-gb-fg-f hover:text-gb-aqua font-mono text-sm"
|
className="text-gb-fg-f hover:text-gb-aqua font-mono text-sm"
|
||||||
>
|
>
|
||||||
[CANCEL]
|
[CANCEL]
|
||||||
|
|||||||
Reference in New Issue
Block a user