style(admin): improve company dropdown layout in user list component
All checks were successful
Staging Build / build (push) Successful in 3m29s
All checks were successful
Staging Build / build (push) Successful in 3m29s
This commit is contained in:
@@ -135,12 +135,12 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
|
||||
const displayUsers = groupByCompany
|
||||
? [...filteredUsers].sort((a, b) => {
|
||||
const nameA = a.company_name || 'Keine Firma'
|
||||
const nameB = b.company_name || 'Keine Firma'
|
||||
if (!a.company_name && b.company_name) return 1
|
||||
if (a.company_name && !b.company_name) return -1
|
||||
return nameA.localeCompare(nameB)
|
||||
})
|
||||
const nameA = a.company_name || 'Keine Firma'
|
||||
const nameB = b.company_name || 'Keine Firma'
|
||||
if (!a.company_name && b.company_name) return 1
|
||||
if (a.company_name && !b.company_name) return -1
|
||||
return nameA.localeCompare(nameB)
|
||||
})
|
||||
: filteredUsers
|
||||
|
||||
console.log('COMPANIES IN USERLIST:', companies)
|
||||
@@ -286,13 +286,12 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
<select
|
||||
value={role}
|
||||
onChange={(e) => handleRoleChange(user.id, e.target.value as Role)}
|
||||
className={`text-xs font-semibold rounded px-3 py-1.5 cursor-pointer focus:outline-none focus:ring-2 transition-colors bg-white dark:bg-slate-950/80 ${
|
||||
role === 'admin'
|
||||
className={`text-xs font-semibold rounded px-3 py-1.5 cursor-pointer focus:outline-none focus:ring-2 transition-colors bg-white dark:bg-slate-950/80 ${role === 'admin'
|
||||
? 'text-purple-600 dark:text-purple-300 border border-purple-500/40 focus:ring-purple-500/50'
|
||||
: role === 'gesperrt'
|
||||
? 'text-red-600 dark:text-red-300 border border-red-500/40 focus:ring-red-500/50'
|
||||
: 'text-blue-600 dark:text-blue-300 border border-blue-500/40 focus:ring-blue-500/50'
|
||||
}`}
|
||||
? 'text-red-600 dark:text-red-300 border border-red-500/40 focus:ring-red-500/50'
|
||||
: 'text-blue-600 dark:text-blue-300 border border-blue-500/40 focus:ring-blue-500/50'
|
||||
}`}
|
||||
style={{ appearance: 'auto' }}
|
||||
>
|
||||
<option value="admin" className="bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100">Admin</option>
|
||||
@@ -322,42 +321,40 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
)}
|
||||
</div>
|
||||
{companyDropdownOpen === user.id && (
|
||||
<div className="absolute z-50 mt-1 right-0 w-56 bg-white dark:bg-slate-900 border border-slate-200 dark:border-white/10 rounded-lg shadow-xl overflow-hidden">
|
||||
<div className="p-2 border-b border-slate-200 dark:border-white/10">
|
||||
<div className="absolute z-50 left-0 right-0 mt-1 bg-white dark:bg-slate-900 border border-slate-200 dark:border-white/10 rounded-md shadow-lg p-1 flex flex-col max-h-60 overflow-y-auto">
|
||||
<div className="flex items-center gap-2 px-2 py-1.5 border-b border-slate-100 dark:border-white/5 mb-1 sticky top-0 bg-white dark:bg-slate-900 z-10">
|
||||
<Search className="h-3.5 w-3.5 text-slate-500 shrink-0" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Firma suchen..."
|
||||
value={companySearch}
|
||||
onChange={(e) => setCompanySearch(e.target.value)}
|
||||
className="w-full text-xs bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 rounded px-2 py-1.5 text-slate-900 dark:text-slate-200 placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-primary/50"
|
||||
autoFocus
|
||||
className="w-full text-xs bg-transparent border-0 p-0 focus:outline-none focus:ring-0 text-slate-900 dark:text-slate-200 placeholder-slate-500"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
/>
|
||||
</div>
|
||||
<div className="max-h-40 overflow-y-auto">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => { handleCompanyChange(user.id, ''); setCompanyDropdownOpen(null); setCompanySearch(''); }}
|
||||
className={`w-full text-left text-xs px-3 py-2 hover:bg-slate-100 dark:hover:bg-white/10 transition-colors ${
|
||||
!user.company_id ? 'text-primary font-semibold' : 'text-slate-700 dark:text-slate-300'
|
||||
}`}
|
||||
>
|
||||
Keine Firma
|
||||
</button>
|
||||
{companies
|
||||
.filter((c) => c.name.toLowerCase().includes(companySearch.toLowerCase()))
|
||||
.map((c) => (
|
||||
<button
|
||||
key={c.id}
|
||||
type="button"
|
||||
onClick={() => { handleCompanyChange(user.id, c.id); setCompanyDropdownOpen(null); setCompanySearch(''); }}
|
||||
className={`w-full text-left text-xs px-3 py-2 hover:bg-slate-100 dark:hover:bg-white/10 transition-colors ${
|
||||
user.company_id === c.id ? 'text-primary font-semibold' : 'text-slate-700 dark:text-slate-300'
|
||||
|
||||
<button
|
||||
onClick={() => handleCompanyChange(user.id, '')}
|
||||
className="w-full text-left px-2 py-1.5 text-xs rounded hover:bg-slate-100 dark:hover:bg-white/5 text-red-500 font-medium"
|
||||
>
|
||||
Keine Firma (Zuweisung aufheben)
|
||||
</button>
|
||||
|
||||
{companies
|
||||
.filter((c) => c.name.toLowerCase().includes(companySearch.toLowerCase()))
|
||||
.map((c) => (
|
||||
<button
|
||||
key={c.id}
|
||||
onClick={() => handleCompanyChange(user.id, c.id)}
|
||||
className={`w-full text-left px-2 py-1.5 text-xs rounded hover:bg-slate-100 dark:hover:bg-white/5 transition-colors ${user.company_id === c.id
|
||||
? 'bg-primary/10 text-primary font-medium'
|
||||
: 'text-slate-700 dark:text-slate-300'
|
||||
}`}
|
||||
>
|
||||
{c.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
>
|
||||
{c.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -367,35 +364,35 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<div className="flex justify-end gap-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8 text-yellow-500 hover:text-yellow-400 hover:bg-yellow-500/10"
|
||||
title="Passwort zurücksetzen"
|
||||
onClick={() => handleResetPassword(user.email)}
|
||||
>
|
||||
<Key className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className={role === 'gesperrt' ? 'h-8 w-8 text-green-500 hover:text-green-400 hover:bg-green-500/10' : 'h-8 w-8 text-red-500 hover:text-red-400 hover:bg-red-500/10'}
|
||||
title={role === 'gesperrt' ? 'Entsperren' : 'Sperren'}
|
||||
onClick={() => handleToggleLock(user.id, role)}
|
||||
disabled={loadingId === user.id + '-lock'}
|
||||
>
|
||||
{loadingId === user.id + '-lock' ? <Loader2 className="h-4 w-4 animate-spin" /> : role === 'gesperrt' ? <Unlock className="h-4 w-4" /> : <Ban className="h-4 w-4" />}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8 text-destructive hover:text-destructive hover:bg-destructive/10"
|
||||
title="Löschen"
|
||||
onClick={() => handleDelete(user.id)}
|
||||
disabled={isLoadingDelete}
|
||||
>
|
||||
{isLoadingDelete ? <Loader2 className="h-4 w-4 animate-spin" /> : <Trash2 className="h-4 w-4" />}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8 text-yellow-500 hover:text-yellow-400 hover:bg-yellow-500/10"
|
||||
title="Passwort zurücksetzen"
|
||||
onClick={() => handleResetPassword(user.email)}
|
||||
>
|
||||
<Key className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className={role === 'gesperrt' ? 'h-8 w-8 text-green-500 hover:text-green-400 hover:bg-green-500/10' : 'h-8 w-8 text-red-500 hover:text-red-400 hover:bg-red-500/10'}
|
||||
title={role === 'gesperrt' ? 'Entsperren' : 'Sperren'}
|
||||
onClick={() => handleToggleLock(user.id, role)}
|
||||
disabled={loadingId === user.id + '-lock'}
|
||||
>
|
||||
{loadingId === user.id + '-lock' ? <Loader2 className="h-4 w-4 animate-spin" /> : role === 'gesperrt' ? <Unlock className="h-4 w-4" /> : <Ban className="h-4 w-4" />}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8 text-destructive hover:text-destructive hover:bg-destructive/10"
|
||||
title="Löschen"
|
||||
onClick={() => handleDelete(user.id)}
|
||||
disabled={isLoadingDelete}
|
||||
>
|
||||
{isLoadingDelete ? <Loader2 className="h-4 w-4 animate-spin" /> : <Trash2 className="h-4 w-4" />}
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
Reference in New Issue
Block a user