feat: list end customers in companies admin and improve dark/light mode contrast across all admin components
All checks were successful
Staging Build / build (push) Successful in 2m36s
All checks were successful
Staging Build / build (push) Successful in 2m36s
This commit is contained in:
@@ -147,10 +147,10 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
let lastCompanyName: string | null = null
|
||||
|
||||
return (
|
||||
<Card className="glass-dark border-white/10 shadow-2xl overflow-visible">
|
||||
<Card className="bg-white dark:bg-slate-900/50 border border-slate-200 dark:border-white/10 shadow-sm overflow-visible text-slate-900 dark:text-white">
|
||||
<CardHeader>
|
||||
<CardTitle>Benutzerverwaltung</CardTitle>
|
||||
<CardDescription className="text-slate-400">
|
||||
<CardDescription className="text-slate-500 dark:text-slate-400">
|
||||
Rollen, Firmenzuweisungen, Passwörter und Benutzerkonten verwalten.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
@@ -163,31 +163,31 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
placeholder="Benutzer suchen (E-Mail, Firma, Rolle)..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full pl-9 pr-4 py-2 text-sm bg-white/5 border border-white/10 rounded-md text-slate-200 placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-slate-950 transition-all"
|
||||
className="w-full pl-9 pr-4 py-2 text-sm bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 rounded-md text-slate-900 dark:text-slate-200 placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-slate-50 dark:focus:ring-offset-slate-950 transition-all"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
<div className="flex items-center gap-2 bg-white/5 border border-white/10 rounded-md px-3 py-2 cursor-pointer hover:bg-white/10 transition-colors">
|
||||
<div className="flex items-center gap-2 bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 rounded-md px-3 py-2 cursor-pointer hover:bg-slate-100 dark:hover:bg-white/10 transition-colors">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="hideLocked"
|
||||
checked={hideLocked}
|
||||
onChange={(e) => setHideLocked(e.target.checked)}
|
||||
className="h-4 w-4 rounded border-white/10 bg-slate-950 text-primary focus:ring-primary focus:ring-offset-slate-950 accent-primary cursor-pointer"
|
||||
className="h-4 w-4 rounded border-slate-200 dark:border-white/10 bg-white dark:bg-slate-950 text-primary focus:ring-primary focus:ring-offset-slate-50 dark:focus:ring-offset-slate-950 accent-primary cursor-pointer"
|
||||
/>
|
||||
<label htmlFor="hideLocked" className="text-xs text-slate-300 font-medium cursor-pointer select-none">
|
||||
<label htmlFor="hideLocked" className="text-xs text-slate-700 dark:text-slate-300 font-medium cursor-pointer select-none">
|
||||
Gesperrte ausblenden
|
||||
</label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 bg-white/5 border border-white/10 rounded-md px-3 py-2 cursor-pointer hover:bg-white/10 transition-colors">
|
||||
<div className="flex items-center gap-2 bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 rounded-md px-3 py-2 cursor-pointer hover:bg-slate-100 dark:hover:bg-white/10 transition-colors">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="groupByCompany"
|
||||
checked={groupByCompany}
|
||||
onChange={(e) => setGroupByCompany(e.target.checked)}
|
||||
className="h-4 w-4 rounded border-white/10 bg-slate-950 text-primary focus:ring-primary focus:ring-offset-slate-950 accent-primary cursor-pointer"
|
||||
className="h-4 w-4 rounded border-slate-200 dark:border-white/10 bg-white dark:bg-slate-950 text-primary focus:ring-primary focus:ring-offset-slate-50 dark:focus:ring-offset-slate-950 accent-primary cursor-pointer"
|
||||
/>
|
||||
<label htmlFor="groupByCompany" className="text-xs text-slate-300 font-medium cursor-pointer select-none">
|
||||
<label htmlFor="groupByCompany" className="text-xs text-slate-700 dark:text-slate-300 font-medium cursor-pointer select-none">
|
||||
Nach Firma gruppieren
|
||||
</label>
|
||||
</div>
|
||||
@@ -195,12 +195,12 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
</div>
|
||||
<Table containerClassName="overflow-visible">
|
||||
<TableHeader>
|
||||
<TableRow className="border-white/10 hover:bg-white/5">
|
||||
<TableHead className="text-slate-200">E-Mail</TableHead>
|
||||
<TableHead className="text-slate-200">Rolle</TableHead>
|
||||
<TableHead className="text-slate-200">Firma</TableHead>
|
||||
<TableHead className="text-slate-200">Zuletzt angemeldet</TableHead>
|
||||
<TableHead className="text-right text-slate-200">Aktionen</TableHead>
|
||||
<TableRow className="border-slate-200 dark:border-white/10 hover:bg-slate-50 dark:hover:bg-white/5">
|
||||
<TableHead className="text-slate-700 dark:text-slate-200">E-Mail</TableHead>
|
||||
<TableHead className="text-slate-700 dark:text-slate-200">Rolle</TableHead>
|
||||
<TableHead className="text-slate-700 dark:text-slate-200">Firma</TableHead>
|
||||
<TableHead className="text-slate-700 dark:text-slate-200">Zuletzt angemeldet</TableHead>
|
||||
<TableHead className="text-right text-slate-700 dark:text-slate-200">Aktionen</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
@@ -217,14 +217,14 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
return (
|
||||
<Fragment key={user.id}>
|
||||
{showGroupHeader && (
|
||||
<TableRow className="bg-white/5 border-y border-white/10 hover:bg-white/5">
|
||||
<TableRow className="bg-slate-50 dark:bg-white/5 border-y border-slate-200 dark:border-white/10 hover:bg-slate-100 dark:hover:bg-white/5">
|
||||
<TableCell colSpan={5} className="font-semibold text-primary py-2 px-4 text-xs tracking-wider uppercase">
|
||||
Firma: {currentCompanyName}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
<TableRow className="border-white/5 hover:bg-white/5 transition-colors">
|
||||
<TableCell className="font-medium text-white">
|
||||
<TableRow className="border-slate-150 dark:border-white/5 hover:bg-slate-50 dark:hover:bg-white/5 transition-colors">
|
||||
<TableCell className="font-medium text-slate-900 dark:text-white">
|
||||
<div className="flex flex-col">
|
||||
<div className="flex items-center gap-2">
|
||||
<Mail className="w-4 h-4 text-slate-500" />
|
||||
@@ -251,7 +251,7 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
(e.target as HTMLInputElement).blur()
|
||||
}
|
||||
}}
|
||||
className="bg-transparent border-b border-transparent hover:border-white/20 focus:border-primary focus:outline-none text-xs text-slate-400 w-20 px-1 py-0.5 transition-all placeholder:text-slate-600 placeholder:italic"
|
||||
className="bg-transparent border-b border-transparent hover:border-slate-300 dark:hover:border-white/20 focus:border-primary focus:outline-none text-xs text-slate-600 dark:text-slate-400 w-20 px-1 py-0.5 transition-all placeholder:text-slate-500 placeholder:italic"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
@@ -273,7 +273,7 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
(e.target as HTMLInputElement).blur()
|
||||
}
|
||||
}}
|
||||
className="bg-transparent border-b border-transparent hover:border-white/20 focus:border-primary focus:outline-none text-xs text-slate-400 w-24 px-1 py-0.5 transition-all placeholder:text-slate-600 placeholder:italic"
|
||||
className="bg-transparent border-b border-transparent hover:border-slate-300 dark:hover:border-white/20 focus:border-primary focus:outline-none text-xs text-slate-600 dark:text-slate-400 w-24 px-1 py-0.5 transition-all placeholder:text-slate-500 placeholder:italic"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -286,18 +286,18 @@ 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 ${
|
||||
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'
|
||||
? 'bg-purple-500/20 text-purple-300 border border-purple-500/40 focus:ring-purple-500/50'
|
||||
? 'text-purple-600 dark:text-purple-300 border border-purple-500/40 focus:ring-purple-500/50'
|
||||
: role === 'gesperrt'
|
||||
? 'bg-red-500/20 text-red-300 border border-red-500/40 focus:ring-red-500/50'
|
||||
: 'bg-blue-500/20 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">Admin</option>
|
||||
<option value="partner">Partner</option>
|
||||
<option value="gesperrt">Gesperrt</option>
|
||||
<option value="admin" className="bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100">Admin</option>
|
||||
<option value="partner" className="bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100">Partner</option>
|
||||
<option value="gesperrt" className="bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100">Gesperrt</option>
|
||||
</select>
|
||||
)}
|
||||
</div>
|
||||
@@ -315,21 +315,21 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
setCompanyDropdownOpen(companyDropdownOpen === user.id ? null : user.id)
|
||||
setCompanySearch('')
|
||||
}}
|
||||
className="text-xs bg-white/5 border border-white/10 rounded px-3 py-1.5 text-slate-300 hover:bg-white/10 cursor-pointer focus:outline-none focus:ring-1 focus:ring-primary/50 max-w-[180px] truncate text-left"
|
||||
className="text-xs bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 rounded px-3 py-1.5 text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-white/10 cursor-pointer focus:outline-none focus:ring-1 focus:ring-primary/50 max-w-[180px] truncate text-left"
|
||||
>
|
||||
{user.company_name || 'Keine Firma'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{companyDropdownOpen === user.id && (
|
||||
<div className="absolute z-50 mt-1 left-0 w-56 bg-slate-900 border border-white/10 rounded-lg shadow-xl overflow-hidden">
|
||||
<div className="p-2 border-b border-white/10">
|
||||
<div className="absolute z-50 mt-1 left-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">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Firma suchen..."
|
||||
value={companySearch}
|
||||
onChange={(e) => setCompanySearch(e.target.value)}
|
||||
className="w-full text-xs bg-white/5 border border-white/10 rounded px-2 py-1.5 text-slate-200 placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-primary/50"
|
||||
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
|
||||
/>
|
||||
</div>
|
||||
@@ -337,8 +337,8 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => { handleCompanyChange(user.id, ''); setCompanyDropdownOpen(null); setCompanySearch(''); }}
|
||||
className={`w-full text-left text-xs px-3 py-2 hover:bg-white/10 transition-colors ${
|
||||
!user.company_id ? 'text-primary font-semibold' : 'text-slate-300'
|
||||
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
|
||||
@@ -350,8 +350,8 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
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-white/10 transition-colors ${
|
||||
user.company_id === c.id ? 'text-primary font-semibold' : 'text-slate-300'
|
||||
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'
|
||||
}`}
|
||||
>
|
||||
{c.name}
|
||||
|
||||
Reference in New Issue
Block a user