- split orders by device_name into FlattenedDevice entries - strip device prefixes from product and module names - render one DeviceCard per Kasse in the customer accordion - add targeted upgrade URL with orderId, customer_id, device_id - wizard starts at step 3 in upgrade mode with locked customer - mark existing licensed modules as read-only with badge
75 lines
3.0 KiB
TypeScript
75 lines
3.0 KiB
TypeScript
export const dynamic = 'force-dynamic';
|
|
import { redirect } from 'next/navigation'
|
|
import Link from 'next/link'
|
|
import { getPartnerCustomersWithDevices } from '@/lib/actions/queries'
|
|
import type { EndCustomerWithDevices } from '@/lib/types'
|
|
import { ArrowLeft, Building2, Plus, AlertTriangle } from 'lucide-react'
|
|
import { Button } from '@/components/ui/button'
|
|
import { createClient } from '@/lib/supabase/server'
|
|
import { CustomerAccordionList } from '@/components/customer-accordion-list'
|
|
|
|
export default async function MyCustomersPage() {
|
|
const supabase = await createClient()
|
|
const { data: { user } } = await supabase.auth.getUser()
|
|
if (!user) redirect('/auth/login')
|
|
|
|
let customers: EndCustomerWithDevices[] = []
|
|
let fetchError: string | null = null
|
|
try {
|
|
customers = await getPartnerCustomersWithDevices()
|
|
} catch (err: any) {
|
|
console.error("Error loading partner customers with orders:", err)
|
|
fetchError = err.message || "Es gab ein Problem beim Laden Ihrer Kunden und Kassen."
|
|
}
|
|
|
|
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" />
|
|
Kunden & Kassen
|
|
</h1>
|
|
<p className="text-slate-400 text-sm mt-1">
|
|
Verwalten Sie Ihre Kunden und deren zugewiesene Kassen / Abonnements.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<Link href="/my-customers/new">
|
|
<Button className="gap-2">
|
|
<Plus className="w-4 h-4" /> Kunde hinzufügen
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
|
|
{fetchError && (
|
|
<div className="p-4 rounded-xl bg-red-500/10 border border-red-500/20 text-red-200 text-sm">
|
|
{fetchError}
|
|
</div>
|
|
)}
|
|
|
|
{/* Akkordeon-Ansicht */}
|
|
<CustomerAccordionList customers={customers} />
|
|
|
|
{/* 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>
|
|
)
|
|
}
|