feat: add customer search and scrollable list to orderwizard
All checks were successful
Staging Build / build (push) Successful in 3m37s
All checks were successful
Staging Build / build (push) Successful in 3m37s
This commit is contained in:
@@ -11,7 +11,7 @@ import { Input } from '@/components/ui/input'
|
|||||||
import { Label } from '@/components/ui/label'
|
import { Label } from '@/components/ui/label'
|
||||||
import { Separator } from '@/components/ui/separator'
|
import { Separator } from '@/components/ui/separator'
|
||||||
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
|
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
|
||||||
import { Check, ChevronRight, ChevronLeft, ShoppingCart, User, ShieldCheck, Cloud, Utensils, HardDrive, Package, AlertCircle, Loader2, UserPlus, Building2, CreditCard, Calendar } from 'lucide-react'
|
import { Check, ChevronRight, ChevronLeft, ShoppingCart, User, ShieldCheck, Cloud, Utensils, HardDrive, Package, AlertCircle, Loader2, UserPlus, Building2, CreditCard, Calendar, Search } from 'lucide-react'
|
||||||
import { submitOrder } from '@/lib/actions/orders'
|
import { submitOrder } from '@/lib/actions/orders'
|
||||||
import { createEndCustomer } from '@/lib/actions/end-customers'
|
import { createEndCustomer } from '@/lib/actions/end-customers'
|
||||||
import { Category } from '@/lib/types'
|
import { Category } from '@/lib/types'
|
||||||
@@ -100,6 +100,32 @@ export function OrderWizard({
|
|||||||
)
|
)
|
||||||
const selectedEndCustomer = endCustomers.find(c => c.id === selectedEndCustomerId) ?? null
|
const selectedEndCustomer = endCustomers.find(c => c.id === selectedEndCustomerId) ?? null
|
||||||
|
|
||||||
|
const [searchTerm, setSearchTerm] = useState('')
|
||||||
|
|
||||||
|
const filteredEndCustomers = useMemo(() => {
|
||||||
|
const activeCustomers = endCustomers.filter(c => !c.is_anonymized)
|
||||||
|
const term = searchTerm.toLowerCase().trim()
|
||||||
|
if (!term) return activeCustomers
|
||||||
|
|
||||||
|
return activeCustomers.filter(customer => {
|
||||||
|
const company = customer.company_name?.toLowerCase() || ''
|
||||||
|
const firstName = customer.first_name?.toLowerCase() || ''
|
||||||
|
const lastName = customer.last_name?.toLowerCase() || ''
|
||||||
|
const street = customer.street?.toLowerCase() || ''
|
||||||
|
const zip = customer.zip?.toLowerCase() || ''
|
||||||
|
const city = customer.city?.toLowerCase() || ''
|
||||||
|
|
||||||
|
return (
|
||||||
|
company.includes(term) ||
|
||||||
|
firstName.includes(term) ||
|
||||||
|
lastName.includes(term) ||
|
||||||
|
street.includes(term) ||
|
||||||
|
zip.includes(term) ||
|
||||||
|
city.includes(term)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}, [endCustomers, searchTerm])
|
||||||
|
|
||||||
// Modus: 'select' = Bestandskunde wählen | 'create' = Neuen anlegen
|
// Modus: 'select' = Bestandskunde wählen | 'create' = Neuen anlegen
|
||||||
const [customerMode, setCustomerMode] = useState<'select' | 'create'>('select')
|
const [customerMode, setCustomerMode] = useState<'select' | 'create'>('select')
|
||||||
const [isCreatingCustomer, setIsCreatingCustomer] = useState(false)
|
const [isCreatingCustomer, setIsCreatingCustomer] = useState(false)
|
||||||
@@ -398,7 +424,7 @@ export function OrderWizard({
|
|||||||
{/* Modus A: Bestandskunde wählen */}
|
{/* Modus A: Bestandskunde wählen */}
|
||||||
{customerMode === 'select' && (
|
{customerMode === 'select' && (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{endCustomers.length === 0 ? (
|
{endCustomers.filter(c => !c.is_anonymized).length === 0 ? (
|
||||||
<div className="p-6 rounded-xl bg-white/5 border border-white/10 text-center space-y-3">
|
<div className="p-6 rounded-xl bg-white/5 border border-white/10 text-center space-y-3">
|
||||||
<Building2 className="w-10 h-10 text-slate-600 mx-auto" />
|
<Building2 className="w-10 h-10 text-slate-600 mx-auto" />
|
||||||
<p className="text-slate-400">Noch keine Endkunden angelegt.</p>
|
<p className="text-slate-400">Noch keine Endkunden angelegt.</p>
|
||||||
@@ -407,8 +433,23 @@ export function OrderWizard({
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-2">
|
<div className="space-y-4">
|
||||||
{endCustomers.filter(c => !c.is_anonymized).map(customer => (
|
<div className="relative">
|
||||||
|
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
|
||||||
|
<Input
|
||||||
|
placeholder="Kunden suchen nach Name, Ort, PLZ..."
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={e => setSearchTerm(e.target.value)}
|
||||||
|
className="pl-9 bg-white/5 border-white/10 text-white placeholder:text-slate-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{filteredEndCustomers.length === 0 ? (
|
||||||
|
<div className="p-6 rounded-xl bg-white/5 border border-white/10 text-center">
|
||||||
|
<p className="text-slate-400">Keine passenden Kunden gefunden.</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="space-y-2 max-h-72 overflow-y-auto pr-1">
|
||||||
|
{filteredEndCustomers.map(customer => (
|
||||||
<label
|
<label
|
||||||
key={customer.id}
|
key={customer.id}
|
||||||
className={`flex items-start p-4 rounded-xl border-2 cursor-pointer transition-all ${
|
className={`flex items-start p-4 rounded-xl border-2 cursor-pointer transition-all ${
|
||||||
@@ -442,6 +483,8 @@ export function OrderWizard({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Modus B: Neuen Kunden anlegen */}
|
{/* Modus B: Neuen Kunden anlegen */}
|
||||||
{customerMode === 'create' && (
|
{customerMode === 'create' && (
|
||||||
|
|||||||
Reference in New Issue
Block a user