Angebote bearbeiten fuer Admin und Ersteller implementiert
All checks were successful
Staging Build / build (push) Successful in 3m51s
All checks were successful
Staging Build / build (push) Successful in 3m51s
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { useState, useMemo } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
import { Product, ProductModule, Profile, EndCustomer } from '@/lib/types'
|
||||
import { Product, ProductModule, Profile, EndCustomer, Order } from '@/lib/types'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from '@/components/ui/card'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
@@ -12,7 +12,7 @@ import { Label } from '@/components/ui/label'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
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, Search } from 'lucide-react'
|
||||
import { submitOrder } from '@/lib/actions/orders'
|
||||
import { submitOrder, updateOrder } from '@/lib/actions/orders'
|
||||
import { createEndCustomer } from '@/lib/actions/end-customers'
|
||||
import { Category } from '@/lib/types'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
@@ -80,11 +80,13 @@ export function OrderWizard({
|
||||
categories,
|
||||
initialProfile,
|
||||
initialEndCustomers,
|
||||
initialOrder,
|
||||
}: {
|
||||
products: Product[]
|
||||
categories: Category[]
|
||||
initialProfile: Profile | null
|
||||
initialEndCustomers: EndCustomer[]
|
||||
initialOrder?: Order | null
|
||||
}) {
|
||||
const router = useRouter()
|
||||
const [step, setStep] = useState(1)
|
||||
@@ -96,7 +98,9 @@ export function OrderWizard({
|
||||
// Endkunden-State
|
||||
const [endCustomers, setEndCustomers] = useState<EndCustomer[]>(initialEndCustomers)
|
||||
const [selectedEndCustomerId, setSelectedEndCustomerId] = useState<string | null>(
|
||||
initialEndCustomers.length > 0 ? initialEndCustomers[0].id : null
|
||||
initialOrder
|
||||
? initialOrder.end_customer_id
|
||||
: (initialEndCustomers.length > 0 ? initialEndCustomers[0].id : null)
|
||||
)
|
||||
const selectedEndCustomer = endCustomers.find(c => c.id === selectedEndCustomerId) ?? null
|
||||
|
||||
@@ -134,13 +138,26 @@ export function OrderWizard({
|
||||
})
|
||||
|
||||
// Abrechnungsmodell-Auswahl ('one_time' = Kauf, 'monthly' = Abo)
|
||||
const [selectedBillingInterval, setSelectedBillingInterval] = useState<'one_time' | 'monthly'>('monthly')
|
||||
const [selectedBillingInterval, setSelectedBillingInterval] = useState<'one_time' | 'monthly'>(
|
||||
initialOrder?.order_data?.billing_cycle ?? 'monthly'
|
||||
)
|
||||
|
||||
// Modulmengen (moduleId -> Menge)
|
||||
const [moduleQuantities, setModuleQuantities] = useState<Record<string, number>>({})
|
||||
const [moduleQuantities, setModuleQuantities] = useState<Record<string, number>>(() => {
|
||||
if (!initialOrder) return {}
|
||||
const quantities: Record<string, number> = {}
|
||||
initialOrder.order_data?.items?.forEach(item => {
|
||||
item.selected_modules?.forEach(mod => {
|
||||
quantities[mod.module_id] = mod.quantity ?? 1
|
||||
})
|
||||
})
|
||||
return quantities
|
||||
})
|
||||
|
||||
// Datum der letzten Lizenz (Bestandskunden-Update-Logik)
|
||||
const [lastLicenseDate, setLastLicenseDate] = useState<string>("")
|
||||
const [lastLicenseDate, setLastLicenseDate] = useState<string>(
|
||||
initialOrder?.order_data?.last_license_date ?? ""
|
||||
)
|
||||
|
||||
const lastLicenseMonths = useMemo(() => {
|
||||
if (!lastLicenseDate || customerMode !== 'select' || !selectedEndCustomerId) return null
|
||||
@@ -174,6 +191,16 @@ export function OrderWizard({
|
||||
const [selections, setSelections] = useState<Record<string, CategorySelection>>(() => {
|
||||
const init: Record<string, CategorySelection> = {}
|
||||
categories.forEach(cat => {
|
||||
if (initialOrder) {
|
||||
const item = initialOrder.order_data?.items?.find(i => i.category_id === cat.id)
|
||||
if (item) {
|
||||
init[cat.id] = {
|
||||
productId: item.product_id,
|
||||
moduleIds: item.selected_modules?.map(m => m.module_id) ?? []
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
const first = products.find(p => p.category_id === cat.id && p.show_in_abo !== false)
|
||||
init[cat.id] = { productId: first?.id ?? null, moduleIds: [] }
|
||||
})
|
||||
@@ -335,21 +362,34 @@ export function OrderWizard({
|
||||
if (isSubmitting) return // Doppelklick-Guard
|
||||
setIsSubmitting(true)
|
||||
try {
|
||||
const order = await submitOrder({
|
||||
selections,
|
||||
moduleQuantities,
|
||||
products,
|
||||
categories,
|
||||
customerProfile: customerData,
|
||||
endCustomerId: selectedEndCustomerId,
|
||||
endCustomer: selectedEndCustomer,
|
||||
billingInterval: selectedBillingInterval,
|
||||
lastLicenseDate: lastLicenseDate || null,
|
||||
})
|
||||
let order
|
||||
if (initialOrder) {
|
||||
order = await updateOrder(initialOrder.id, {
|
||||
selections,
|
||||
moduleQuantities,
|
||||
customerProfile: customerData,
|
||||
endCustomerId: selectedEndCustomerId,
|
||||
endCustomer: selectedEndCustomer,
|
||||
billingInterval: selectedBillingInterval,
|
||||
lastLicenseDate: lastLicenseDate || null,
|
||||
})
|
||||
} else {
|
||||
order = await submitOrder({
|
||||
selections,
|
||||
moduleQuantities,
|
||||
products,
|
||||
categories,
|
||||
customerProfile: customerData,
|
||||
endCustomerId: selectedEndCustomerId,
|
||||
endCustomer: selectedEndCustomer,
|
||||
billingInterval: selectedBillingInterval,
|
||||
lastLicenseDate: lastLicenseDate || null,
|
||||
})
|
||||
}
|
||||
router.push(`/order/success?id=${order.id}`)
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
console.error(error)
|
||||
alert('Fehler bei der Bestellung. Bitte versuchen Sie es erneut.')
|
||||
alert(error?.message || (initialOrder ? 'Fehler beim Aktualisieren des Angebots.' : 'Fehler bei der Bestellung. Bitte versuchen Sie es erneut.'))
|
||||
setIsSubmitting(false) // Nur bei Fehler wieder entsperren
|
||||
}
|
||||
}
|
||||
@@ -1106,9 +1146,13 @@ export function OrderWizard({
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
{isSubmitting ? (
|
||||
<><Loader2 className="mr-2 h-5 w-5 animate-spin" /> Bestellung wird verarbeitet...</>
|
||||
initialOrder ? (
|
||||
<><Loader2 className="mr-2 h-5 w-5 animate-spin" /> Angebot wird aktualisiert...</>
|
||||
) : (
|
||||
<><Loader2 className="mr-2 h-5 w-5 animate-spin" /> Bestellung wird verarbeitet...</>
|
||||
)
|
||||
) : (
|
||||
'Kostenpflichtig bestellen'
|
||||
initialOrder ? 'Angebot aktualisieren' : 'Kostenpflichtig bestellen'
|
||||
)}
|
||||
</Button>
|
||||
<Button variant="ghost" className="w-full text-white" onClick={prevStep}>
|
||||
|
||||
Reference in New Issue
Block a user