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

This commit is contained in:
DanielS
2026-06-25 02:11:07 +02:00
parent bf27c62f62
commit ef9422908d
11 changed files with 222 additions and 240 deletions

View File

@@ -13,8 +13,7 @@ import {
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog'
import { getCompanies, createCompany, updateCompany, deleteCompany } from '@/lib/actions/companies'
import { getUsersByCompany } from '@/lib/actions/users'
import { getCompanies, createCompany, updateCompany, deleteCompany, getEndCustomersByCompany } from '@/lib/actions/companies'
export default function CompaniesPage() {
const [companies, setCompanies] = useState<any[]>([])
@@ -33,10 +32,10 @@ export default function CompaniesPage() {
const [deletingId, setDeletingId] = useState<string | null>(null)
const [searchQuery, setSearchQuery] = useState('')
const [isUsersOpen, setIsUsersOpen] = useState(false)
const [selectedCompanyForUsers, setSelectedCompanyForUsers] = useState<any>(null)
const [companyUsers, setCompanyUsers] = useState<any[]>([])
const [loadingUsers, setLoadingUsers] = useState(false)
const [isCustomersOpen, setIsCustomersOpen] = useState(false)
const [selectedCompanyForCustomers, setSelectedCompanyForCustomers] = useState<any>(null)
const [companyCustomers, setCompanyCustomers] = useState<any[]>([])
const [loadingCustomers, setLoadingCustomers] = useState(false)
const loadCompanies = async () => {
setLoading(true)
@@ -91,17 +90,17 @@ export default function CompaniesPage() {
}
}
const handleShowUsers = async (company: any) => {
setSelectedCompanyForUsers(company)
setIsUsersOpen(true)
setLoadingUsers(true)
const handleShowCustomers = async (company: any) => {
setSelectedCompanyForCustomers(company)
setIsCustomersOpen(true)
setLoadingCustomers(true)
try {
const data = await getUsersByCompany(company.id)
setCompanyUsers(data)
const data = await getEndCustomersByCompany(company.id)
setCompanyCustomers(data)
} catch (err) {
console.error('Fehler beim Laden der Benutzer:', err)
console.error('Fehler beim Laden der Endkunden:', err)
} finally {
setLoadingUsers(false)
setLoadingCustomers(false)
}
}
@@ -212,9 +211,9 @@ export default function CompaniesPage() {
<Button
variant="ghost"
size="icon"
onClick={() => handleShowUsers(company)}
onClick={() => handleShowCustomers(company)}
className="h-8 w-8 text-indigo-500 hover:text-indigo-400 hover:bg-indigo-500/10"
title="Benutzer anzeigen"
title="Endkunden dieser Firma anzeigen"
>
<Users className="h-4 w-4" />
</Button>
@@ -342,60 +341,54 @@ export default function CompaniesPage() {
</DialogContent>
</Dialog>
{/* Dialog: Benutzer der Firma anzeigen */}
<Dialog open={isUsersOpen} onOpenChange={(val) => {
setIsUsersOpen(val);
{/* Dialog: Endkunden der Firma anzeigen */}
<Dialog open={isCustomersOpen} onOpenChange={(val) => {
setIsCustomersOpen(val);
if (!val) {
setCompanyUsers([]);
setCompanyCustomers([]);
}
}}>
<DialogContent className="bg-white dark:bg-slate-950 border-slate-200 dark:border-white/10 text-slate-900 dark:text-white shadow-2xl">
<DialogHeader>
<DialogTitle>
Benutzer von {selectedCompanyForUsers?.name}
Endkunden von {selectedCompanyForCustomers?.name}
</DialogTitle>
<DialogDescription className="text-slate-500 dark:text-slate-400">
Liste aller Benutzer, die dieser Firma zugewiesen sind.
Liste aller Endkunden, die von den Partnern dieser Firma betreut werden.
</DialogDescription>
</DialogHeader>
<div className="py-4">
{loadingUsers ? (
{loadingCustomers ? (
<div className="flex justify-center items-center py-8">
<Loader2 className="w-6 h-6 text-indigo-500 animate-spin" />
<span className="ml-2 text-slate-400 text-sm">Lade Benutzer...</span>
<span className="ml-2 text-slate-400 text-sm">Lade Endkunden...</span>
</div>
) : companyUsers.length === 0 ? (
) : companyCustomers.length === 0 ? (
<p className="text-center text-slate-500 text-sm py-8">
Keine Benutzer für diese Firma registriert.
Keine Endkunden für diese Firma registriert.
</p>
) : (
<div className="space-y-3 max-h-60 overflow-y-auto pr-1">
{companyUsers.map((user) => (
<div key={user.id} className="flex justify-between items-center p-3 rounded-lg bg-slate-50 dark:bg-white/5 border border-slate-100 dark:border-white/5">
<div>
<p className="text-sm font-semibold text-slate-900 dark:text-white">
{user.first_name || user.last_name ? `${user.first_name} ${user.last_name}` : 'Kein Name'}
</p>
<p className="text-xs text-slate-500 dark:text-slate-400">
{user.email}
</p>
{companyCustomers.map((customer) => (
<div key={customer.id} className="flex flex-col gap-1 p-3 rounded-lg bg-slate-50 dark:bg-white/5 border border-slate-100 dark:border-white/5">
<p className="text-sm font-semibold text-slate-900 dark:text-white">
{customer.company_name}
</p>
<div className="flex justify-between items-center text-xs text-slate-500 dark:text-slate-400">
<span>
{customer.first_name || customer.last_name ? `${customer.first_name || ''} ${customer.last_name || ''}`.trim() : 'Kein Ansprechpartner'}
</span>
<span>
{customer.zip} {customer.city}
</span>
</div>
<span className={`text-[10px] font-bold uppercase rounded-full px-2.5 py-0.5 border ${
user.role === 'admin'
? 'bg-purple-500/10 text-purple-400 border-purple-500/30'
: user.role === 'gesperrt'
? 'bg-red-500/10 text-red-400 border-red-500/30'
: 'bg-blue-500/10 text-blue-400 border-blue-500/30'
}`}>
{user.role}
</span>
</div>
))}
</div>
)}
</div>
<DialogFooter>
<Button onClick={() => { setIsUsersOpen(false); setCompanyUsers([]); }} className="bg-slate-800 hover:bg-slate-700 text-white font-semibold">
<Button onClick={() => { setIsCustomersOpen(false); setCompanyCustomers([]); }} className="bg-slate-800 hover:bg-slate-700 text-white font-semibold">
Schließen
</Button>
</DialogFooter>

View File

@@ -25,9 +25,9 @@ export default async function AdminLayout({
}
return (
<div className="flex min-h-screen bg-[#020617] text-white">
<div className="flex min-h-screen bg-slate-50 dark:bg-[#020617] text-slate-900 dark:text-white">
{/* Sidebar */}
<aside className="w-64 border-r border-white/5 bg-black/20 backdrop-blur-xl flex flex-col">
<aside className="w-64 border-r border-slate-200 dark:border-white/5 bg-white dark:bg-black/20 backdrop-blur-xl flex flex-col">
<div className="p-6">
<Link href="/" className="flex items-center gap-2">
<div className="w-8 h-8 bg-primary rounded-lg flex items-center justify-center">
@@ -38,55 +38,55 @@ export default async function AdminLayout({
</div>
<nav className="flex-1 px-4 space-y-2 py-4">
<Link href="/admin" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Link href="/admin" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-white/5 transition-all">
<LayoutDashboard className="w-5 h-5" />
Dashboard
</Link>
<Link href="/admin/products" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Link href="/admin/products" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-white/5 transition-all">
<Package className="w-5 h-5" />
Produkte
</Link>
<Link href="/admin/categories" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Link href="/admin/categories" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-white/5 transition-all">
<LayoutGrid className="w-5 h-5" />
Kategorien
</Link>
<Link href="/admin/orders" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Link href="/admin/orders" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-white/5 transition-all">
<ShoppingCart className="w-5 h-5" />
Bestellungen
</Link>
<Link href="/admin/users" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Link href="/admin/users" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-white/5 transition-all">
<Users className="w-5 h-5" />
Benutzer
</Link>
<Link href="/admin/companies" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Link href="/admin/companies" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-white/5 transition-all">
<Building2 className="w-5 h-5" />
Firmen
</Link>
<div className="pt-2 pb-1 px-3">
<span className="text-[10px] font-semibold uppercase tracking-wider text-slate-600">Einstellungen</span>
<span className="text-[10px] font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-600">Einstellungen</span>
</div>
<Link href="/admin/einstellungen" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Link href="/admin/einstellungen" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-white/5 transition-all">
<Settings className="w-5 h-5" />
Allgemein
</Link>
<Link href="/admin/settings" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Link href="/admin/settings" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-white/5 transition-all">
<Wrench className="w-5 h-5" />
SMTP
</Link>
<Link href="/admin/tools" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/5 transition-all">
<Link href="/admin/tools" className="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-slate-100 dark:hover:bg-white/5 transition-all">
<Database className="w-5 h-5" />
DB-Tools
</Link>
</nav>
<div className="p-4 border-t border-white/5 space-y-4">
<div className="p-4 border-t border-slate-200 dark:border-white/5 space-y-4">
<AdminLogoutButton />
<div className="px-3 pt-2 flex items-center gap-2 border-t border-white/5 opacity-60">
<span className="font-bold text-sm tracking-tighter text-white">CASPOS Store</span>
<div className="px-3 pt-2 flex items-center gap-2 border-t border-slate-200 dark:border-white/5 opacity-60">
<span className="font-bold text-sm tracking-tighter text-slate-800 dark:text-white">CASPOS Store</span>
<DemoWrapper>
<span className="text-[10px] bg-amber-500/20 text-amber-400 px-2 py-0.5 rounded-full font-semibold uppercase tracking-wider border border-amber-500/30">
<span className="text-[10px] bg-amber-500/20 text-amber-600 dark:text-amber-400 px-2 py-0.5 rounded-full font-semibold uppercase tracking-wider border border-amber-500/30">
Demo
</span>
</DemoWrapper>