import { Settings2 } from 'lucide-react'; import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { Field, FieldDescription, FieldGroup, FieldLabel, } from '@/components/ui/field'; import { Input } from '@/components/ui/input'; import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Separator } from '@/components/ui/separator'; import { Textarea } from '@/components/ui/textarea'; import type { WAFIPGroup, WAFRuleNode } from '@/lib/services/openflare'; const countries = [ 'CN', 'US', 'JP', 'SG', 'DE', 'FR', 'GB', 'CA', 'AU', 'BR', 'IN', 'KR', ].map((value) => ({ value, label: value })); const regions = [ 'CN-BJ', 'CN-SH', 'CN-GD', 'CN-ZJ', 'US-CA', 'US-NY', 'US-TX', 'JP-13', 'DE-BE', 'GB-ENG', ].map((value) => ({ value, label: value })); export function NodeProperties({ node, ipGroups, onChange, }: { node: WAFRuleNode; ipGroups: WAFIPGroup[]; onChange: (node: WAFRuleNode) => void; }) { return ( ); } function PropertyFields({ node, ipGroups, onChange, }: { node: WAFRuleNode; ipGroups: WAFIPGroup[]; onChange: (node: WAFRuleNode) => void; }) { if (node.type === 'start' || node.type === 'allow') return

系统节点无需配置。

; if (node.type === 'ip_match') return ( onChange({ ...node, config: { ...node.config, ips } }) } /> onChange({ ...node, config: { ...node.config, cidrs } }) } /> ({ value: String(group.id), label: group.name, }))} value={node.config.ip_group_ids.map(String)} onChange={(values) => onChange({ ...node, config: { ...node.config, ip_group_ids: values.map(Number) }, }) } /> ); if (node.type === 'geo_match') return ( onChange({ ...node, config: { ...node.config, countries } }) } /> onChange({ ...node, config: { ...node.config, regions } }) } /> ); if (node.type === 'pow') return ( 算法 {(['difficulty', 'session_ttl', 'challenge_ttl'] as const).map( (key) => ( onChange({ ...node, config: { ...node.config, [key]: value } }) } /> ), )} ); return ( onChange({ ...node, config: { ...node.config, status_code } }) } /> HTML 响应体