1import {
2 Button,
3 FormControl,
4 FormField,
5 FormItem,
6 Input,
7 SortableDragHandle,
8 SortableItem,
9 Select,
10 SelectContent,
11 SelectItem,
12 SelectTrigger,
13 SelectValue,
14 DeleteConfirmation
15} from "@marzneshin/common/components";
16import { useDialog } from "@marzneshin/common/hooks";
17import {
18 Schema
19} from "./schema"
20import {
21 useFormContext,
22 FieldArrayWithId,
23 UseFieldArrayRemove
24} from "react-hook-form";
25import { DragHandleDots2Icon, TrashIcon } from "@radix-ui/react-icons"
26
27interface RuleItemProps {
28 index: number;
29 field: FieldArrayWithId<Schema, "rules">;
30 onRemove: UseFieldArrayRemove;
31}
32
33export const RuleItem = ({ index, field, onRemove: remove }: RuleItemProps) => {
34 const form = useFormContext();
35 const [deleteDialogOpen, setDeleteDialogOpen] = useDialog(false);
36
37 return (
38 <>
39 <DeleteConfirmation
40 open={deleteDialogOpen}
41 onOpenChange={setDeleteDialogOpen}
42 action={() => remove(index)}
43 />
44 <SortableItem key={field.id} value={field.id} asChild>
45 <div className="grid grid-cols-[2fr,1.3fr,0.25fr,0.25fr] items-center justify-start gap-2 my-2">
46 <FormField
47 control={form.control}
48 name={`rules.${index}.pattern`}
49 render={({ field }) => (
50 <FormItem>
51 <FormControl>
52 <div>
53 <Input className="h-8" {...field} />
54 </div>
55 </FormControl>
56 </FormItem>
57 )}
58 />
59 <FormField
60 control={form.control}
61 name={`rules.${index}.result`}
62 render={({ field }) => (
63 <FormItem>
64 <Select onValueChange={field.onChange} defaultValue={field.value}>
65 <FormControl>
66 <div>
67 <SelectTrigger className="h-8 p-2">
68 <SelectValue />
69 </SelectTrigger>
70 </div>
71 </FormControl>
72 <SelectContent>
73 <SelectItem value="xray">xray</SelectItem>
74 <SelectItem value="sing-box">sing-box</SelectItem>
75 <SelectItem value="clash">clash</SelectItem>
76 <SelectItem value="clash-meta">clash-meta</SelectItem>
77 <SelectItem value="block">block</SelectItem>
78 <SelectItem value="template">template</SelectItem>
79 <SelectItem value="base64-links">base64-links</SelectItem>
80 <SelectItem value="links">links</SelectItem>
81 </SelectContent>
82 </Select>
83 </FormItem>
84 )}
85 />
86 <SortableDragHandle
87 variant="outline"
88 size="icon"
89 className="size-8 shrink-0"
90 >
91 <DragHandleDots2Icon
92 className="size-4"
93 aria-hidden="true"
94 />
95 </SortableDragHandle>
96 <Button
97 type="button"
98 variant="outline"
99 size="icon"
100 className="size-8 shrink-0"
101 onClick={() => setDeleteDialogOpen(true)}
102 >
103 <TrashIcon
104 className="size-4 text-destructive"
105 aria-hidden="true"
106 />
107 <span className="sr-only">Remove</span>
108 </Button>
109 </div>
110 </SortableItem>
111 </>
112 )
113}