Files
webshop/shop/app/my-customers/page.tsx
DanielS 0e4495292d feat(my-customers): flatten orders into per-device cards
- 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
2026-07-23 09:45:14 +02:00

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>
)
}