Skip to content
Merged
11 changes: 2 additions & 9 deletions app/admin/add-barometer/add-manufacturer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ interface AddManufacturerProps {
onAddManufacturer: (newId: string) => void
}

interface ManufacturerFormData {
firstName: string
name: string
city: string
countries: number[]
description: string
icon: string | null
}

// Yup validation schema
const manufacturerSchema = yup.object().shape({
firstName: yup.string().max(100, 'First name should be shorter than 100 characters').default(''),
Expand All @@ -39,6 +30,8 @@ const manufacturerSchema = yup.object().shape({
icon: yup.string().nullable().default(null),
})

type ManufacturerFormData = yup.InferType<typeof manufacturerSchema>

export function AddManufacturer({ onAddManufacturer }: AddManufacturerProps) {
const { countries } = useBarometers()
const [open, setOpen] = useState(false)
Expand Down
90 changes: 90 additions & 0 deletions app/admin/add-barometer/add-materials.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
'use client'

import { Check, X } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from '@/components/ui/command'

interface MaterialsMultiSelectProps {
value: number[]
onChange: (value: number[]) => void
materials: Array<{ id: number; name: string }>
}

export function MaterialsMultiSelect({ value, onChange, materials }: MaterialsMultiSelectProps) {
const selectedMaterials = materials.filter(material => value.includes(material.id))

const handleSelect = (materialId: number) => {
if (value.includes(materialId)) {
onChange(value.filter(id => id !== materialId))
} else {
onChange([...value, materialId])
}
}

const handleRemove = (materialId: number) => {
onChange(value.filter(id => id !== materialId))
}

return (
<div className="space-y-2">
{selectedMaterials.length > 0 && (
<div className="flex flex-wrap gap-2">
{selectedMaterials.map(material => (
<Badge key={material.id} variant="default" className="px-2 py-1">
{material.name}
<Button
type="button"
variant="ghost"
size="sm"
className="ml-1 h-auto p-0"
onClick={() => handleRemove(material.id)}
>
<X className="h-3 w-3" />
</Button>
</Badge>
))}
</div>
)}
<Popover modal>
<PopoverTrigger asChild>
<Button type="button" variant="outline" className="w-full justify-start">
{selectedMaterials.length === 0
? 'Select materials...'
: `${selectedMaterials.length} material${selectedMaterials.length === 1 ? '' : 's'} selected`}
</Button>
</PopoverTrigger>
<PopoverContent className="w-full p-0" align="start">
<Command>
<CommandInput placeholder="Search materials..." />
<CommandList className="max-h-[200px]">
<CommandEmpty>No materials found.</CommandEmpty>
<CommandGroup>
{materials.map(material => (
<CommandItem
key={material.id}
onSelect={() => handleSelect(material.id)}
className="flex items-center space-x-2"
>
<div className="flex h-4 w-4 items-center justify-center">
{value.includes(material.id) && <Check className="h-3 w-3" />}
</div>
<span>{material.name}</span>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</div>
)
}
7 changes: 6 additions & 1 deletion app/admin/add-barometer/file-upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ interface FileUploadProps {
export function FileUpload({ name }: FileUploadProps) {
const [isUploading, setIsUploading] = useState(false)
const fileInputRef = useRef<HTMLInputElement>(null)
const { control, watch, setValue } = useFormContext()
const { control, watch, setValue, clearErrors } = useFormContext()

const fileNames: string[] = watch(name) || []

Expand Down Expand Up @@ -47,6 +47,7 @@ export function FileUpload({ name }: FileUploadProps) {

const newFileNames = [...fileNames, ...urlsDto.urls.map(urlObj => urlObj.public)]
setValue(name, newFileNames)
clearErrors(name) // Clear any validation errors after successful upload
} catch (error) {
toast.error(error instanceof Error ? error.message : 'Error uploading files')
} finally {
Expand All @@ -62,6 +63,10 @@ export function FileUpload({ name }: FileUploadProps) {
await deleteImage(fileName)
const updatedFileNames = fileNames.filter((_, i) => i !== index)
setValue(name, updatedFileNames)
// Clear errors if we still have images after deletion
if (updatedFileNames.length > 0) {
clearErrors(name)
}
} catch (error) {
toast.error(error instanceof Error ? error.message : 'Error deleting file')
}
Expand Down
Loading
Loading