Files
lunarfront-app/packages/admin/src/components/inventory/supplier-form.tsx
Ryan Moon 5f5ba9e4a2 Build inventory frontend and stock management features
- Full inventory UI: product list with search/filter, product detail with
  tabs (details, units, suppliers, stock receipts, price history)
- Product filters: category, type (serialized/rental/repair), low stock,
  active/inactive — all server-side with URL-synced state
- Product-supplier junction: link products to multiple suppliers with
  preferred flag, joined supplier details in UI
- Stock receipts: record incoming stock with supplier, qty, cost per unit,
  invoice number; auto-increments qty_on_hand for non-serialized products
- Price history tab on product detail page
- categories/all endpoint to avoid pagination limit on dropdown fetches
- categoryId filter on product list endpoint
- Repair parts and additional inventory items in music store seed data
- isDualUseRepair corrected: instruments set to false, strings/parts true
- Product-supplier links and stock receipts in seed data
- Price history seed data simulating cost increases over past year
- 37 API tests covering categories, suppliers, products, units,
  product-suppliers, and stock receipts
- alert-dialog and checkbox UI components
- sync-and-deploy.sh script for rsync + remote deploy
2026-03-30 20:12:07 -05:00

89 lines
3.3 KiB
TypeScript

import { useForm } from 'react-hook-form'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import type { Supplier } from '@/types/inventory'
interface Props {
defaultValues?: Partial<Supplier>
onSubmit: (data: Record<string, unknown>) => void
onDelete?: () => void
loading?: boolean
deleteLoading?: boolean
}
export function SupplierForm({ defaultValues, onSubmit, onDelete, loading, deleteLoading }: Props) {
const { register, handleSubmit } = useForm({
defaultValues: {
name: defaultValues?.name ?? '',
contactName: defaultValues?.contactName ?? '',
email: defaultValues?.email ?? '',
phone: defaultValues?.phone ?? '',
website: defaultValues?.website ?? '',
accountNumber: defaultValues?.accountNumber ?? '',
paymentTerms: defaultValues?.paymentTerms ?? '',
},
})
function handleFormSubmit(data: Record<string, string>) {
onSubmit({
name: data.name,
contactName: data.contactName || undefined,
email: data.email || undefined,
phone: data.phone || undefined,
website: data.website || undefined,
accountNumber: data.accountNumber || undefined,
paymentTerms: data.paymentTerms || undefined,
})
}
return (
<form onSubmit={handleSubmit(handleFormSubmit)} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="sup-name">Name *</Label>
<Input id="sup-name" {...register('name')} placeholder="e.g. Fender Musical Instruments" required />
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="sup-contact">Contact Name</Label>
<Input id="sup-contact" {...register('contactName')} placeholder="Jane Smith" />
</div>
<div className="space-y-2">
<Label htmlFor="sup-email">Email</Label>
<Input id="sup-email" type="email" {...register('email')} placeholder="orders@supplier.com" />
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="sup-phone">Phone</Label>
<Input id="sup-phone" {...register('phone')} placeholder="555-0100" />
</div>
<div className="space-y-2">
<Label htmlFor="sup-website">Website</Label>
<Input id="sup-website" {...register('website')} placeholder="https://supplier.com" />
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="sup-acct">Account Number</Label>
<Input id="sup-acct" {...register('accountNumber')} placeholder="ACC-12345" />
</div>
<div className="space-y-2">
<Label htmlFor="sup-terms">Payment Terms</Label>
<Input id="sup-terms" {...register('paymentTerms')} placeholder="Net 30" />
</div>
</div>
<div className="flex gap-2 pt-2">
<Button type="submit" disabled={loading} className="flex-1">
{loading ? 'Saving...' : defaultValues?.id ? 'Save Changes' : 'Create Supplier'}
</Button>
{onDelete && (
<Button type="button" variant="destructive" disabled={deleteLoading} onClick={onDelete}>
{deleteLoading ? 'Deleting...' : 'Delete'}
</Button>
)}
</div>
</form>
)
}