'use client' import React, { useState, useMemo, useEffect } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { Card, CardHeader, CardTitle, CardDescription } from '@/components/ui/card' import { Label } from '@/components/ui/label' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Badge } from '@/components/ui/badge' import { User, Building2, UserPlus, Search, Check, Loader2, ChevronRight, ChevronLeft, ChevronsLeft, ChevronsRight, Users, ChevronDown, ChevronUp, X, CreditCard, Mail, MapPin, CheckCircle2, Building, } from 'lucide-react' import { EndCustomer } from '@/lib/types' interface StepCustomerProps { isAdmin: boolean companies: any[] selectedCompanyId: string | null setSelectedCompanyId: (id: string | null) => void customerMode: 'select' | 'create' setCustomerMode: (mode: 'select' | 'create') => void endCustomers: EndCustomer[] searchTerm: string setSearchTerm: (term: string) => void filteredEndCustomers: EndCustomer[] selectedEndCustomerId: string | null setSelectedEndCustomerId: (id: string | null) => void newCustomerForm: any setNewCustomerForm: React.Dispatch> handleCreateCustomer: () => Promise isCreatingCustomer: boolean nextStep: () => void } export function StepCustomer({ isAdmin, companies, selectedCompanyId, setSelectedCompanyId, customerMode, setCustomerMode, endCustomers, searchTerm, setSearchTerm, selectedEndCustomerId, setSelectedEndCustomerId, newCustomerForm, setNewCustomerForm, handleCreateCustomer, isCreatingCustomer, nextStep, }: StepCustomerProps) { // ─── PARTNER SELECTION STATE & PAGINATION (Admins only) ────────────────────── const [partnerSearchTerm, setPartnerSearchTerm] = useState('') const [partnerPageSize, setPartnerPageSize] = useState(10) const [partnerCurrentPage, setPartnerCurrentPage] = useState(1) // Drawer / Sheet state for customer creation const [showBankDetails, setShowBankDetails] = useState(false) // Drawer visibility is mapped to customerMode === 'create' const isDrawerOpen = customerMode === 'create' const openDrawer = () => setCustomerMode('create') const closeDrawer = () => { setCustomerMode('select') setShowBankDetails(false) } useEffect(() => { setPartnerCurrentPage(1) }, [partnerSearchTerm, partnerPageSize]) // Count non-anonymized customers per partner company const customerCountMap = useMemo(() => { const counts: Record = {} endCustomers.forEach((c) => { if (!c.is_anonymized && c.partner_id) { counts[c.partner_id] = (counts[c.partner_id] || 0) + 1 } }) return counts }, [endCustomers]) const filteredCompanies = useMemo(() => { const term = partnerSearchTerm.toLowerCase().trim() if (!term) return companies return companies.filter( (c: any) => c.name?.toLowerCase().includes(term) || c.id?.toLowerCase().includes(term) ) }, [companies, partnerSearchTerm]) const totalPartnerCount = filteredCompanies.length const totalPartnerPages = Math.ceil(totalPartnerCount / partnerPageSize) || 1 const paginatedCompanies = useMemo(() => { const from = (partnerCurrentPage - 1) * partnerPageSize return filteredCompanies.slice(from, from + partnerPageSize) }, [filteredCompanies, partnerCurrentPage, partnerPageSize]) // ─── CUSTOMER SELECTION STATE & PAGINATION ────────────────────────────────── const [pageSize, setPageSize] = useState(10) const [currentPage, setCurrentPage] = useState(1) useEffect(() => { setCurrentPage(1) }, [searchTerm, selectedCompanyId, pageSize]) // Filter customers by selected partner (if admin and selectedCompanyId != 'all') const customersByCompany = useMemo(() => { let list = endCustomers.filter((c) => !c.is_anonymized) if (isAdmin && selectedCompanyId && selectedCompanyId !== 'all') { list = list.filter((c) => c.partner_id === selectedCompanyId) } return list }, [endCustomers, isAdmin, selectedCompanyId]) // Customer search filter const filteredCustomers = useMemo(() => { const term = searchTerm.toLowerCase().trim() if (!term) return customersByCompany return customersByCompany.filter( (c) => c.company_name?.toLowerCase().includes(term) || c.first_name?.toLowerCase().includes(term) || c.last_name?.toLowerCase().includes(term) || c.city?.toLowerCase().includes(term) || c.zip?.toLowerCase().includes(term) || c.email?.toLowerCase().includes(term) ) }, [customersByCompany, searchTerm]) const totalCustomerCount = filteredCustomers.length const totalCustomerPages = Math.ceil(totalCustomerCount / pageSize) || 1 const paginatedCustomers = useMemo(() => { const from = (currentPage - 1) * pageSize return filteredCustomers.slice(from, from + pageSize) }, [filteredCustomers, currentPage, pageSize]) // Selected customer object for summary chip / info const activeCustomer = useMemo(() => { return endCustomers.find((c) => c.id === selectedEndCustomerId) || null }, [endCustomers, selectedEndCustomerId]) // Click handler for customer selection const handleSelectCustomer = (customer: EndCustomer) => { setSelectedEndCustomerId(customer.id) if (isAdmin && customer.partner_id && (selectedCompanyId === 'all' || !selectedCompanyId)) { setSelectedCompanyId(customer.partner_id) } } // Handle form submission with enter or button const onSubmitCustomerForm = async (e: React.FormEvent) => { e.preventDefault() if (!newCustomerForm.company_name?.trim()) return await handleCreateCustomer() } return ( <> {/* ─── 1. FIXED HEADER (shrink-0) ─── */}
Für wen bestellen Sie? Wählen Sie den Endkunden für die Lizenzierung aus oder legen Sie schnell einen neuen Datensatz an.
{/* ─── 2. SCROLLABLE MIDDLE CONTENT (flex-1 min-h-0 overflow-hidden) ─── */}
{/* ─── 2A. ADMIN PARTNER SELECTION ─── */} {isAdmin && (

Filtert die Kundenliste nach Partner

Admin Modus
{/* Partner Search & Page Size */}
setPartnerSearchTerm(e.target.value)} className="pl-8 bg-white/5 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
{/* Partner Card List (Scrollable) */}
{/* Reserved Fixed Card: Alle Partner */}
{ setSelectedCompanyId('all') setSelectedEndCustomerId(null) }} className={`flex items-center justify-between p-2.5 rounded-xl border cursor-pointer transition-all select-none ${ selectedCompanyId === 'all' || !selectedCompanyId ? 'border-primary bg-primary/10 shadow-sm shadow-primary/10' : 'border-white/5 bg-white/5 hover:bg-white/10' }`} >

Alle Partner (Firmenübergreifend)

{endCustomers.filter((c) => !c.is_anonymized).length} Kunden gesamt

{(selectedCompanyId === 'all' || !selectedCompanyId) && ( )}
{/* Dynamic Partner Cards */} {paginatedCompanies.map((c: any) => { const isSelected = selectedCompanyId === c.id const customerCount = customerCountMap[c.id] || 0 return (
{ setSelectedCompanyId(c.id) setSelectedEndCustomerId(null) }} className={`flex items-center justify-between p-2.5 rounded-xl border cursor-pointer transition-all select-none ${ isSelected ? 'border-primary bg-primary/10 shadow-sm shadow-primary/10' : 'border-white/5 bg-white/5 hover:bg-white/10' }`} >

{c.name}

{(c.street || c.zip || c.city) && (

{[c.street, [c.zip, c.city].filter(Boolean).join(' ')].filter(Boolean).join(', ')}

)}
0 ? 'border-green-500/30 text-green-400 bg-green-500/10' : 'border-white/10 text-slate-500 bg-white/5' }`} > {customerCount} {isSelected && }
) })} {filteredCompanies.length === 0 && (
Keine Partner gefunden.
)}
{/* Partner Pagination Footer */}
{Math.min(partnerCurrentPage * partnerPageSize, totalPartnerCount)} / {totalPartnerCount} Partner
{partnerCurrentPage} / {totalPartnerPages}
)} {/* ─── 2B. CUSTOMER SELECTION LIST (Scrollable Panel) ─── */}

{isAdmin && selectedCompanyId && selectedCompanyId !== 'all' ? `Partner: "${companies.find((c) => c.id === selectedCompanyId)?.name || selectedCompanyId}"` : 'Alle Endkunden'}

{/* Customer Search */}
setSearchTerm(e.target.value)} className="pl-8 bg-white/5 border-white/10 text-white placeholder:text-slate-500 text-xs h-8" />
{/* Customer Card List (Isolated Scrollable Area) */}
{customersByCompany.length === 0 ? (

{isAdmin && selectedCompanyId && selectedCompanyId !== 'all' ? 'Keine Endkunden für den ausgewählten Partner vorhanden.' : 'Noch keine Endkunden vorhanden.'}

) : filteredCustomers.length === 0 ? (
Keine passenden Kunden für "{searchTerm}" gefunden.
) : ( paginatedCustomers.map((customer) => { const isSelected = selectedEndCustomerId === customer.id return (
handleSelectCustomer(customer)} className={`flex items-start p-3 rounded-xl border-2 cursor-pointer transition-all select-none ${ isSelected ? 'border-primary bg-primary/10 shadow-md shadow-primary/5' : 'border-white/5 bg-white/5 hover:bg-white/10' }`} > handleSelectCustomer(customer)} className="sr-only" />

{customer.company_name}

{isAdmin && customer.partner_id && ( Partner: {companies.find((co) => co.id === customer.partner_id)?.name || customer.partner_id} )}

{[customer.first_name, customer.last_name].filter(Boolean).join(' ')} {customer.first_name || customer.last_name ? ' · ' : ''} {[customer.street, customer.zip, customer.city].filter(Boolean).join(', ')}

{customer.email && (

{customer.email}

)}
{isSelected && }
) }) )}
{/* Customer Pagination */} {totalCustomerCount > 0 && (
{Math.min(currentPage * pageSize, totalCustomerCount)} / {totalCustomerCount} Kunden
{currentPage} / {totalCustomerPages}
)}
{/* ─── 3. FIXED BOTTOM ACTION BAR (shrink-0) ─── */}
{/* Selected Customer Summary Chip */}
{activeCustomer ? (
Ausgewählt:{' '} {activeCustomer.company_name} {(activeCustomer.city || activeCustomer.zip) && ( ({[activeCustomer.zip, activeCustomer.city].filter(Boolean).join(' ')}) )}
) : (
Bitte wählen Sie einen Kunden aus, um fortzufahren.
)}
{/* Next Button */}
{/* ─── 4. SLIDE-OVER DRAWER FOR CUSTOMER CREATION ─── */} {isDrawerOpen && (
{/* Backdrop */}
{/* Drawer Header */}

Neuen Kunden anlegen

{isAdmin && selectedCompanyId && selectedCompanyId !== 'all' ? `Für Partner: ${companies.find((c) => c.id === selectedCompanyId)?.name || selectedCompanyId}` : 'Erstellen und direkt für die Bestellung auswählen'}

{/* Drawer Body / Form */}
{/* Basic Info Section */}
Stammdaten & Anschrift
setNewCustomerForm((prev: any) => ({ ...prev, company_name: e.target.value })) } placeholder="z. B. Musterfirma GmbH & Co. KG" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
setNewCustomerForm((prev: any) => ({ ...prev, vat_id: e.target.value })) } placeholder="z. B. DE123456789" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
setNewCustomerForm((prev: any) => ({ ...prev, email: e.target.value })) } placeholder="buchhaltung@muster.de" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
setNewCustomerForm((prev: any) => ({ ...prev, first_name: e.target.value })) } placeholder="Max" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
setNewCustomerForm((prev: any) => ({ ...prev, last_name: e.target.value })) } placeholder="Mustermann" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
setNewCustomerForm((prev: any) => ({ ...prev, street: e.target.value })) } placeholder="Hauptstraße 12" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
setNewCustomerForm((prev: any) => ({ ...prev, zip: e.target.value })) } placeholder="10115" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
setNewCustomerForm((prev: any) => ({ ...prev, city: e.target.value })) } placeholder="Berlin" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
{/* Collapsible Bank Details Section */}
{showBankDetails && (
setNewCustomerForm((prev: any) => ({ ...prev, bank_owner: e.target.value })) } placeholder="Max Mustermann" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
setNewCustomerForm((prev: any) => ({ ...prev, bank_iban: e.target.value })) } placeholder="DE89370400440532013000" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8 font-mono" />
setNewCustomerForm((prev: any) => ({ ...prev, bank_bic: e.target.value })) } placeholder="SOLADE21XXX" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8 font-mono" />
setNewCustomerForm((prev: any) => ({ ...prev, bank_name: e.target.value })) } placeholder="Musterbank" className="bg-slate-950/70 border-white/10 text-white placeholder:text-slate-500 focus:border-primary text-xs h-8" />
)}
{/* Drawer Footer */}
)}
) }