diff --git a/app/sites/[id]/funnels/new/page.tsx b/app/sites/[id]/funnels/new/page.tsx index a0d1ec5..c4e9990 100644 --- a/app/sites/[id]/funnels/new/page.tsx +++ b/app/sites/[id]/funnels/new/page.tsx @@ -6,6 +6,15 @@ import { createFunnel, type CreateFunnelRequest, type FunnelStep } from '@/lib/a import { toast, Input, Button, ChevronLeftIcon, PlusIcon, TrashIcon } from '@ciphera-net/ui' import Link from 'next/link' +function isValidRegex(pattern: string): boolean { + try { + new RegExp(pattern) + return true + } catch { + return false + } +} + export default function CreateFunnelPage() { const params = useParams() const router = useRouter() @@ -13,6 +22,7 @@ export default function CreateFunnelPage() { const [name, setName] = useState('') const [description, setDescription] = useState('') + // * Backend requires at least one step (API binding min=1, DB rejects empty steps) const [steps, setSteps] = useState[]>([ { name: 'Step 1', value: '/', type: 'exact' }, { name: 'Step 2', value: '', type: 'exact' } @@ -47,6 +57,10 @@ export default function CreateFunnelPage() { toast.error('Please enter a path for all steps') return } + if (steps.some(s => s.type === 'regex' && !isValidRegex(s.value))) { + toast.error('Invalid regex in one or more steps. Check the pattern for steps with type "regex".') + return + } try { setSaving(true) diff --git a/lib/api/funnels.ts b/lib/api/funnels.ts index ad5fde7..d28eb6b 100644 --- a/lib/api/funnels.ts +++ b/lib/api/funnels.ts @@ -66,7 +66,7 @@ export async function deleteFunnel(siteId: string, funnelId: string): Promise