Files
webshop/shop/app/my-customers/page.tsx

152 lines
6.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'
import Link from 'next/link'
import { getEndCustomers } from '@/lib/actions/end-customers'
import { ArrowLeft, Building2, Plus, Edit2, AlertTriangle } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
export default async function MyCustomersPage() {
const supabase = await createClient()
const { data: { user } } = await supabase.auth.getUser()
if (!user) redirect('/auth/login')
const customers = await getEndCustomers()
// Anzahl Bestellungen pro Endkunde
const { data: orderCounts } = await supabase
.from('orders')
.select('end_customer_id')
.not('end_customer_id', 'is', null)
const countMap: Record<string, number> = {}
;(orderCounts ?? []).forEach(o => {
if (o.end_customer_id) {
countMap[o.end_customer_id] = (countMap[o.end_customer_id] ?? 0) + 1
}
})
return (
<div className="min-h-screen bg-[#020617] text-white px-4 py-12">
<div className="max-w-5xl mx-auto space-y-8">
{/* Header */}
<div className="flex items-center justify-between gap-4 flex-wrap">
<div className="flex items-center gap-4">
<Link href="/">
<Button variant="ghost" size="sm" className="text-slate-400 hover:text-white">
<ArrowLeft className="w-4 h-4 mr-2" /> Startseite
</Button>
</Link>
<div>
<h1 className="text-3xl font-extrabold tracking-tight flex items-center gap-3">
<Building2 className="w-8 h-8 text-primary" />
Meine Kunden
</h1>
<p className="text-slate-400 text-sm mt-1">
Verwalten Sie Ihre Endkunden deren Daten werden für Bestellungen verwendet.
</p>
</div>
</div>
<Link href="/my-customers/new">
<Button className="gap-2">
<Plus className="w-4 h-4" /> Kunde hinzufügen
</Button>
</Link>
</div>
{/* Keine Kunden */}
{customers.length === 0 && (
<Card className="glass-dark border-white/10">
<CardContent className="flex flex-col items-center justify-center py-16 gap-4">
<Building2 className="w-12 h-12 text-slate-600" />
<p className="text-slate-400 text-lg">Noch keine Endkunden angelegt.</p>
<Link href="/my-customers/new">
<Button><Plus className="w-4 h-4 mr-2" /> Ersten Kunden anlegen</Button>
</Link>
</CardContent>
</Card>
)}
{/* Kundenliste */}
{customers.length > 0 && (
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="border-b border-white/10 text-left">
<th className="pb-3 text-xs font-semibold text-slate-400 uppercase tracking-wider">Unternehmen</th>
<th className="pb-3 text-xs font-semibold text-slate-400 uppercase tracking-wider hidden sm:table-cell">Adresse</th>
<th className="pb-3 text-xs font-semibold text-slate-400 uppercase tracking-wider hidden md:table-cell">Bestellungen</th>
<th className="pb-3 text-xs font-semibold text-slate-400 uppercase tracking-wider">Status</th>
<th className="pb-3 text-xs font-semibold text-slate-400 uppercase tracking-wider text-right">Aktionen</th>
</tr>
</thead>
<tbody className="divide-y divide-white/5">
{customers.map(customer => (
<tr key={customer.id} className="hover:bg-white/3 transition-colors">
<td className="py-4 pr-4">
<p className="font-semibold text-white">{customer.company_name}</p>
{(customer.first_name || customer.last_name) && (
<p className="text-sm text-slate-400">
{[customer.first_name, customer.last_name].filter(Boolean).join(' ')}
</p>
)}
{customer.vat_id && (
<p className="text-xs text-slate-500">{customer.vat_id}</p>
)}
</td>
<td className="py-4 pr-4 hidden sm:table-cell">
<p className="text-sm text-slate-300">
{customer.street ?? ''}
</p>
<p className="text-sm text-slate-400">
{[customer.zip, customer.city].filter(Boolean).join(' ') || ''}
</p>
</td>
<td className="py-4 pr-4 hidden md:table-cell">
<Link href={`/my-orders?customer=${customer.id}`} className="group">
<span className="text-primary font-bold group-hover:underline">
{countMap[customer.id] ?? 0}
</span>
<span className="text-slate-500 text-xs ml-1">Bestellung(en)</span>
</Link>
</td>
<td className="py-4 pr-4">
{customer.is_anonymized ? (
<Badge className="bg-red-500/10 text-red-400 border-red-500/20 gap-1">
<AlertTriangle className="w-3 h-3" /> Anonymisiert
</Badge>
) : (
<Badge className="bg-green-500/10 text-green-400 border-green-500/20">Aktiv</Badge>
)}
</td>
<td className="py-4 text-right">
{!customer.is_anonymized && (
<Link href={`/my-customers/${customer.id}`}>
<Button variant="ghost" size="sm" className="text-slate-400 hover:text-white gap-1">
<Edit2 className="w-3.5 h-3.5" /> Bearbeiten
</Button>
</Link>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
{/* DSGVO-Hinweis */}
<div className="p-4 rounded-xl bg-amber-500/5 border border-amber-500/20 text-xs text-amber-300/80 space-y-1">
<p className="font-semibold flex items-center gap-2"><AlertTriangle className="w-3.5 h-3.5" /> DSGVO-Hinweis</p>
<p>
Die hier gespeicherten Kundendaten unterliegen der DSGVO. Auf Wunsch Ihrer Endkunden können Sie deren Daten
über die Bearbeitungsmaske anonymisieren (Recht auf Vergessenwerden). Bestehende Bestellungen bleiben aus
steuerrechtlichen Gründen unverändert.
</p>
</div>
</div>
</div>
)
}