'use client' import { useState } from 'react' import { wearPartSchema, WearPartType, WearPartStatus } from '@/lib/validations' interface WearPartFormProps { bikeId: string onSuccess: () => void onCancel: () => void } const wearPartTypes = [ 'CHAIN', 'BRAKE_PADS', 'TIRE', 'CASSETTE', 'CHAINRING', 'DERAILLEUR', 'BRAKE_CABLE', 'SHIFT_CABLE', 'BRAKE_ROTOR', 'PEDAL', 'CRANKSET', 'BOTTOM_BRACKET', 'HEADSET', 'WHEEL', 'HUB', 'SPOKE', 'OTHER', ] const wearPartStatuses = ['ACTIVE', 'NEEDS_SERVICE', 'REPLACED', 'INACTIVE'] export default function WearPartForm({ bikeId, onSuccess, onCancel, }: WearPartFormProps) { const [formData, setFormData] = useState({ type: 'CHAIN', brand: '', model: '', installDate: new Date().toISOString().split('T')[0], installMileage: 0, serviceInterval: 1000, status: 'ACTIVE', cost: '', notes: '', }) const [errors, setErrors] = useState>({}) const [isSubmitting, setIsSubmitting] = useState(false) const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setErrors({}) setIsSubmitting(true) try { const validatedData = wearPartSchema.parse({ bikeId, type: formData.type, brand: formData.brand || undefined, model: formData.model || undefined, installDate: formData.installDate, installMileage: Number(formData.installMileage), serviceInterval: Number(formData.serviceInterval), status: formData.status, cost: formData.cost ? Number(formData.cost) : undefined, notes: formData.notes || undefined, }) const response = await fetch(`/api/bikes/${bikeId}/parts`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(validatedData), }) if (response.ok) { onSuccess() setFormData({ type: 'CHAIN', brand: '', model: '', installDate: new Date().toISOString().split('T')[0], installMileage: 0, serviceInterval: 1000, status: 'ACTIVE', cost: '', notes: '', }) } else { const errorData = await response.json() if (errorData.details) { const zodErrors: Record = {} errorData.details.errors?.forEach((err: any) => { if (err.path) { zodErrors[err.path[0]] = err.message } }) setErrors(zodErrors) } else { alert('Fehler beim Erstellen des Verschleißteils') } } } catch (error: any) { if (error.errors) { const zodErrors: Record = {} error.errors.forEach((err: any) => { if (err.path) { zodErrors[err.path[0]] = err.message } }) setErrors(zodErrors) } else { console.error('Error creating part:', error) alert('Fehler beim Erstellen des Verschleißteils') } } finally { setIsSubmitting(false) } } return (

Neues Verschleißteil hinzufügen

{errors.type && (

{errors.type}

)}
setFormData({ ...formData, brand: e.target.value }) } className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-black" />
setFormData({ ...formData, model: e.target.value }) } className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-black" />
setFormData({ ...formData, installDate: e.target.value }) } className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-black" required /> {errors.installDate && (

{errors.installDate}

)}
setFormData({ ...formData, installMileage: Number(e.target.value), }) } min="0" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-black" required /> {errors.installMileage && (

{errors.installMileage}

)}
setFormData({ ...formData, serviceInterval: Number(e.target.value), }) } min="1" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-black" required /> {errors.serviceInterval && (

{errors.serviceInterval}

)}
setFormData({ ...formData, cost: e.target.value }) } min="0" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-black" />