From 74f6f63673ea4ba96a16bc94393dcd31f280062e Mon Sep 17 00:00:00 2001 From: Sadrinho27 Date: Fri, 7 Nov 2025 19:44:13 +0100 Subject: [PATCH] Added new ui components --- components/ui/command.tsx | 184 ++++++++++++++++++++++++++ components/ui/dialog.tsx | 143 ++++++++++++++++++++ components/ui/member-autocomplete.tsx | 111 ++++++++++++++++ components/ui/popover.tsx | 48 +++++++ 4 files changed, 486 insertions(+) create mode 100644 components/ui/command.tsx create mode 100644 components/ui/dialog.tsx create mode 100644 components/ui/member-autocomplete.tsx create mode 100644 components/ui/popover.tsx diff --git a/components/ui/command.tsx b/components/ui/command.tsx new file mode 100644 index 0000000..8cb4ca7 --- /dev/null +++ b/components/ui/command.tsx @@ -0,0 +1,184 @@ +"use client" + +import * as React from "react" +import { Command as CommandPrimitive } from "cmdk" +import { SearchIcon } from "lucide-react" + +import { cn } from "@/lib/utils" +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" + +function Command({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function CommandDialog({ + title = "Command Palette", + description = "Search for a command to run...", + children, + className, + showCloseButton = true, + ...props +}: React.ComponentProps & { + title?: string + description?: string + className?: string + showCloseButton?: boolean +}) { + return ( + + + {title} + {description} + + + + {children} + + + + ) +} + +function CommandInput({ + className, + ...props +}: React.ComponentProps) { + return ( +
+ + +
+ ) +} + +function CommandList({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function CommandEmpty({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function CommandGroup({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function CommandSeparator({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function CommandItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function CommandShortcut({ + className, + ...props +}: React.ComponentProps<"span">) { + return ( + + ) +} + +export { + Command, + CommandDialog, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, + CommandShortcut, + CommandSeparator, +} diff --git a/components/ui/dialog.tsx b/components/ui/dialog.tsx new file mode 100644 index 0000000..d9ccec9 --- /dev/null +++ b/components/ui/dialog.tsx @@ -0,0 +1,143 @@ +"use client" + +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { XIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Dialog({ + ...props +}: React.ComponentProps) { + return +} + +function DialogTrigger({ + ...props +}: React.ComponentProps) { + return +} + +function DialogPortal({ + ...props +}: React.ComponentProps) { + return +} + +function DialogClose({ + ...props +}: React.ComponentProps) { + return +} + +function DialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DialogContent({ + className, + children, + showCloseButton = true, + ...props +}: React.ComponentProps & { + showCloseButton?: boolean +}) { + return ( + + + + {children} + {showCloseButton && ( + + + Close + + )} + + + ) +} + +function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function DialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, +} diff --git a/components/ui/member-autocomplete.tsx b/components/ui/member-autocomplete.tsx new file mode 100644 index 0000000..676d753 --- /dev/null +++ b/components/ui/member-autocomplete.tsx @@ -0,0 +1,111 @@ +"use client" + +import * as React from "react" +import { Check, ChevronsUpDown, X } from "lucide-react" + +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command" +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover" +import { Badge } from "@/components/ui/badge" + +interface MemberAutocompleteProps { + allMembers: string[]; + selectedMembers: string[]; + onChange: (selectedMembers: string[]) => void; +} + +export function MemberAutocomplete({ + allMembers, + selectedMembers, + onChange, +}: MemberAutocompleteProps) { + const [open, setOpen] = React.useState(false) + + // Liste des membres qui ne sont PAS encore sélectionnés + const availableMembers = allMembers.filter( + (member) => !selectedMembers.includes(member) + ) + + // Gère la sélection d'un membre dans la liste + const handleSelect = (memberId: string) => { + onChange([...selectedMembers, memberId]) + setOpen(false) // Ferme le popover après sélection + } + + // Gère la suppression d'un membre (clic sur le 'X' du badge) + const handleRemove = (memberId: string) => { + onChange(selectedMembers.filter((m) => m !== memberId)) + } + + return ( +
+ {/* 1. Affichage des membres déjà sélectionnés (Badges) */} +
+ {selectedMembers.map((member) => ( + + {member} + + + ))} +
+ + {/* 2. Le Popover avec le bouton de recherche */} + + + + + + + + + Aucun membre trouvé. + + {availableMembers.map((member) => ( + handleSelect(member)} + className="truncate" + > + {member} + + ))} + + + + + +
+ ) +} \ No newline at end of file diff --git a/components/ui/popover.tsx b/components/ui/popover.tsx new file mode 100644 index 0000000..01e468b --- /dev/null +++ b/components/ui/popover.tsx @@ -0,0 +1,48 @@ +"use client" + +import * as React from "react" +import * as PopoverPrimitive from "@radix-ui/react-popover" + +import { cn } from "@/lib/utils" + +function Popover({ + ...props +}: React.ComponentProps) { + return +} + +function PopoverTrigger({ + ...props +}: React.ComponentProps) { + return +} + +function PopoverContent({ + className, + align = "center", + sideOffset = 4, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +function PopoverAnchor({ + ...props +}: React.ComponentProps) { + return +} + +export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }