'use client' import React, { useState, useMemo, useEffect } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } 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, } 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) 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) ) }, [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]) // Click handler for customer selection const handleSelectCustomer = (customer: EndCustomer) => { setSelectedEndCustomerId(customer.id) if (isAdmin && customer.partner_id && (selectedCompanyId === 'all' || !selectedCompanyId)) { setSelectedCompanyId(customer.partner_id) } } return ( Für wen bestellen Sie? Wählen Sie den Partner (für Admins) und den Endkunden aus oder legen Sie einen neuen an. {/* Modus-Toggle: Bestandskunde vs. Neuer Kunde */}
{/* ─── 1. ADMIN PARTNER SELECTION ─── */} {isAdmin && (

Wählen Sie einen Partner aus, um dessen Kunden anzuzeigen, oder "Alle Partner".

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

Alle Partner (Firmenübergreifend)

Zeigt Kunden aller registrierten Partnerunternehmen an

{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-3.5 rounded-xl border-2 cursor-pointer transition-all select-none ${ isSelected ? 'border-primary bg-primary/10 shadow-lg shadow-primary/5' : '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} {customerCount === 1 ? 'Kunde' : 'Kunden'} {isSelected && }
) })} {filteredCompanies.length === 0 && (
Keine Partner mit dem Suchbegriff "{partnerSearchTerm}" gefunden.
)}
{/* Partner Pagination Controls */}
Zeige {totalPartnerCount === 0 ? 0 : (partnerCurrentPage - 1) * partnerPageSize + 1} bis{' '} {Math.min(partnerCurrentPage * partnerPageSize, totalPartnerCount)} von {totalPartnerCount} Partnern
Seite {partnerCurrentPage} von {totalPartnerPages}
)} {/* ─── 2. CUSTOMER SELECTION ─── */} {customerMode === 'select' && (

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

{customersByCompany.length === 0 ? (

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

) : (
{/* Customer Header Controls: Search & Page Size */}
setSearchTerm(e.target.value)} className="pl-9 bg-white/5 border-white/10 text-white placeholder:text-slate-500 text-sm h-9" />
{/* Page Size Selector */}
Kunden pro Seite:
{filteredCustomers.length === 0 ? (
Keine passenden Kunden gefunden.
) : (
{/* Customer Card List */}
{paginatedCustomers.map((customer) => { const isSelected = selectedEndCustomerId === customer.id return (
handleSelectCustomer(customer)} className={`flex items-start p-3.5 rounded-xl border-2 cursor-pointer transition-all select-none ${ isSelected ? 'border-primary bg-primary/10 shadow-lg 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(', ')}

{isSelected && }
); })}
{/* Customer Pagination Footer */}
Zeige {totalCustomerCount === 0 ? 0 : (currentPage - 1) * pageSize + 1} bis{' '} {Math.min(currentPage * pageSize, totalCustomerCount)} von {totalCustomerCount} Kunden
Seite {currentPage} von {totalCustomerPages}
)}
)}
)} {/* ─── MODUS B: NEUEN KUNDEN ANLEGEN ─── */} {customerMode === 'create' && ( {( [ { label: 'Firmenname *', key: 'company_name', span: true, placeholder: 'GmbH / Einzelunternehmen' }, { label: 'USt-IdNr.', key: 'vat_id', span: false, placeholder: 'DE123456789' }, { label: 'Vorname', key: 'first_name', span: false, placeholder: '' }, { label: 'Nachname', key: 'last_name', span: false, placeholder: '' }, { label: 'Straße & Hausnummer', key: 'street', span: true, placeholder: '' }, { label: 'PLZ', key: 'zip', span: false, placeholder: '' }, { label: 'Ort', key: 'city', span: false, placeholder: '' }, { label: 'Kontoinhaber', key: 'bank_owner', span: false, placeholder: 'Max Mustermann' }, { label: 'IBAN', key: 'bank_iban', span: false, placeholder: 'DE89370400440532013000' }, { label: 'BIC', key: 'bank_bic', span: false, placeholder: 'SOLADE21XXX' }, { label: 'Bankname', key: 'bank_name', span: false, placeholder: 'Musterbank' }, ] as const ).map(({ label, key, span, placeholder }) => (
setNewCustomerForm((prev: any) => ({ ...prev, [key]: e.target.value })) } placeholder={placeholder} className="bg-white/5 border-white/10 text-white placeholder:text-slate-500" />
))}
)}
) }