// * Packages import { usePage } from "@inertiajs/react"; import { useEffect, useMemo, useState } from "react"; // * Components shadcn import { Label } from "@/components/ui/label"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; // * Other import InputError from "@/back/Components/InputError"; import { AppEnv, Model, TranslationField } from "@/back/types/global"; import { cn } from "@/lib/utils"; import { CheckIcon, ChevronsUpDownIcon, XIcon } from "lucide-react"; import { Button } from "@/components/ui/button"; import useTrans from "@/hooks/use-translations"; import BtnOptionnalLinkWithTooltip from "../BtnOptionnalLinkWithTooltip"; import str from "@/hooks/use-string"; type ModelSelectProps = { name: string; label: string; placeholder?: string; options: Array; field: string; required?: boolean; disabled?: boolean; selected?: number | null; setData: (name: string, value: number | null) => void; onSelectValue?: (value: string | null) => void; }; export default function ModelSelect({ name, label, placeholder = "ex: Magnifique libellé", options = [], field = "label", selected = null, required = true, disabled = false, setData, onSelectValue, }: ModelSelectProps) { const { locale } = usePage().props.appEnv as AppEnv; const { errors } = usePage().props; const [open, setOpen] = useState(false); const [selectedId, setSelectedId] = useState( selected ?? null, ); // Get label of an option. const getFieldLabel = (option: Model): string => { const value = option[field as keyof typeof option]; if (typeof value === "object") { return String((value as TranslationField)[locale]); } return String(value ?? ""); }; // Sort the options list. const sortedModels = useMemo(() => { return [...options].sort( (model1, model2) => getFieldLabel(model1) > getFieldLabel(model2), ); }, [options, field, locale]); // Get the label of the selected value. const getSelectedLabel = (): string => { const current = sortedModels.find((model) => model.id === selectedId); return current ? getFieldLabel(current) : placeholder; }; // Update the field. const handleSelect = (modelId: number) => { const selectedModel = sortedModels.find((m) => m.id === modelId); const value = selectedModel ? getFieldLabel(selectedModel) : null; setSelectedId(modelId); setData(name, modelId); if (onSelectValue) onSelectValue(value); setOpen(false); }; // Reset the value. const handleClear = () => { setSelectedId(null); setData(name, null); if (onSelectValue) onSelectValue(null); }; useEffect(() => { const selectedModel = sortedModels.find((m) => m.id === selectedId); const value = selectedModel ? getFieldLabel(selectedModel) : null; if (onSelectValue) onSelectValue(value); }, []); return (
{useTrans("back.table_no_results")} {sortedModels.map((option) => ( handleSelect(option.id) } > {getFieldLabel(option)} ))} {!required && selectedId !== null && ( } tooltipContent={

{str(useTrans("crud.actions.delete")) .ucFirst() .value()}

} type="button" variant="destructive" size="icon" onClick={handleClear} /> )}
); }