feat(ui): Add dropdown for Add User/Origin button
- Single dropdown button shows both options - Selecting an option switches to that tab and opens modal - Cleaner UX than separate buttons per tab 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import { useState, useEffect } from 'react';
|
|||||||
import { Layout } from '../components/Layout';
|
import { Layout } from '../components/Layout';
|
||||||
import { api } from '../lib/api';
|
import { api } from '../lib/api';
|
||||||
import { useAuthStore } from '../store/authStore';
|
import { useAuthStore } from '../store/authStore';
|
||||||
import { Users as UsersIcon, Plus, Pencil, Trash2, X, Check, AlertCircle, Globe, Shield, Power, PowerOff } from 'lucide-react';
|
import { Users as UsersIcon, Plus, Pencil, Trash2, X, Check, AlertCircle, Globe, Shield, Power, PowerOff, ChevronDown } from 'lucide-react';
|
||||||
|
|
||||||
interface User {
|
interface User {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -56,6 +56,9 @@ export function Users() {
|
|||||||
const [originsLoading, setOriginsLoading] = useState(true);
|
const [originsLoading, setOriginsLoading] = useState(true);
|
||||||
const [originsError, setOriginsError] = useState<string | null>(null);
|
const [originsError, setOriginsError] = useState<string | null>(null);
|
||||||
const [showOriginModal, setShowOriginModal] = useState(false);
|
const [showOriginModal, setShowOriginModal] = useState(false);
|
||||||
|
|
||||||
|
// Add dropdown state
|
||||||
|
const [showAddDropdown, setShowAddDropdown] = useState(false);
|
||||||
const [editingOrigin, setEditingOrigin] = useState<TrustedOrigin | null>(null);
|
const [editingOrigin, setEditingOrigin] = useState<TrustedOrigin | null>(null);
|
||||||
const [originFormData, setOriginFormData] = useState<OriginFormData>({ name: '', origin_type: 'domain', origin_value: '', description: '' });
|
const [originFormData, setOriginFormData] = useState<OriginFormData>({ name: '', origin_type: 'domain', origin_value: '', description: '' });
|
||||||
const [originFormError, setOriginFormError] = useState<string | null>(null);
|
const [originFormError, setOriginFormError] = useState<string | null>(null);
|
||||||
@@ -344,24 +347,46 @@ export function Users() {
|
|||||||
<p className="text-sm text-gray-500">Manage users and trusted origins</p>
|
<p className="text-sm text-gray-500">Manage users and trusted origins</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{activeTab === 'users' ? (
|
<div className="relative">
|
||||||
<button
|
<button
|
||||||
onClick={() => { setShowCreateModal(true); setFormError(null); }}
|
onClick={() => setShowAddDropdown(!showAddDropdown)}
|
||||||
|
onBlur={() => setTimeout(() => setShowAddDropdown(false), 150)}
|
||||||
className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
|
className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
|
||||||
>
|
>
|
||||||
<Plus className="w-4 h-4" />
|
<Plus className="w-4 h-4" />
|
||||||
|
Add
|
||||||
|
<ChevronDown className="w-4 h-4" />
|
||||||
|
</button>
|
||||||
|
{showAddDropdown && (
|
||||||
|
<div className="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg border border-gray-200 py-1 z-50">
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setActiveTab('users');
|
||||||
|
setShowCreateModal(true);
|
||||||
|
setFormError(null);
|
||||||
|
setShowAddDropdown(false);
|
||||||
|
}}
|
||||||
|
className="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center gap-2"
|
||||||
|
>
|
||||||
|
<UsersIcon className="w-4 h-4" />
|
||||||
Add User
|
Add User
|
||||||
</button>
|
</button>
|
||||||
) : (
|
|
||||||
<button
|
<button
|
||||||
onClick={() => { setShowOriginModal(true); setOriginFormError(null); }}
|
onClick={() => {
|
||||||
className="flex items-center gap-2 px-4 py-2 bg-emerald-600 text-white rounded-lg hover:bg-emerald-700 transition-colors"
|
setActiveTab('origins');
|
||||||
|
setShowOriginModal(true);
|
||||||
|
setOriginFormError(null);
|
||||||
|
setShowAddDropdown(false);
|
||||||
|
}}
|
||||||
|
className="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center gap-2"
|
||||||
>
|
>
|
||||||
<Plus className="w-4 h-4" />
|
<Globe className="w-4 h-4" />
|
||||||
Add Origin
|
Add Origin
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Tabs */}
|
{/* Tabs */}
|
||||||
<div className="border-b border-gray-200">
|
<div className="border-b border-gray-200">
|
||||||
|
|||||||
Reference in New Issue
Block a user