wacrm/src/app/(dashboard)/automations/[id]/edit/page.tsx
Arnas Donauskas 32022c13fe
feat(theme): sweep remaining violet-* → primary across all surfaces
PR #132 (color themes) only tokenized the high-visibility chrome.
Inbox / contacts / pipelines / broadcasts / automations / auth /
settings sub-forms still had ~150 hard-coded `violet-*` classes
across ~32 files, so picking a non-violet theme felt half-broken —
sidebar and header changed colour, but message bubbles, deal cards,
and the broadcast wizard all stayed violet.

This is the mechanical follow-up: replace every `violet-N(/N)?`
with `primary(/N)?` so the theme picker themes the whole app.

Two non-trivial swaps inside the pass:
- `text-white` on a `bg-primary` button → `text-primary-foreground`.
  Emerald and Amber define a *dark* `--primary-foreground` because
  their primaries are bright; `text-white` over those would tank
  contrast.
- `bg-primary hover:bg-primary` (hover identical to base — original
  code had this latent bug from `hover:bg-violet-500`) → adds `/90`
  on hover so the lift is visible.

Test update:
- `broadcast-status.test.ts` asserted shade numbers (`bg-X-N/10`).
  Relaxed the regex to also accept token form (`bg-X/10`) since
  brand-accent status badges now ride the active theme.

Files touched: 49. Lint clean (existing warnings only), 173/173
tests, typecheck + build green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 17:00:32 +03:00

75 lines
2.0 KiB
TypeScript

"use client"
import { use, useEffect, useState } from "react"
import { useRouter } from "next/navigation"
import { Loader2 } from "lucide-react"
import {
AutomationBuilder,
fromServerSteps,
type BuilderInitial,
type ServerStepNode,
} from "@/components/automations/automation-builder"
import type { AutomationTriggerType } from "@/types"
export default function EditAutomationPage({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = use(params)
const router = useRouter()
const [initial, setInitial] = useState<BuilderInitial | null>(null)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
let cancelled = false
async function load() {
const res = await fetch(`/api/automations/${id}`)
if (!res.ok) {
if (!cancelled) setError(`Failed to load (${res.status})`)
return
}
const body = await res.json()
if (cancelled) return
setInitial({
id: body.automation.id,
name: body.automation.name ?? "",
description: body.automation.description ?? "",
trigger_type: body.automation.trigger_type as AutomationTriggerType,
trigger_config: body.automation.trigger_config ?? {},
is_active: !!body.automation.is_active,
steps: fromServerSteps((body.steps ?? []) as ServerStepNode[]),
})
}
load()
return () => {
cancelled = true
}
}, [id])
if (error) {
return (
<div className="flex h-screen flex-col items-center justify-center gap-3">
<p className="text-sm text-red-400">{error}</p>
<button
onClick={() => router.push("/automations")}
className="text-sm text-primary hover:text-primary/80"
>
Back to Automations
</button>
</div>
)
}
if (!initial) {
return (
<div className="flex h-screen items-center justify-center">
<Loader2 className="h-6 w-6 animate-spin text-primary" />
</div>
)
}
return <AutomationBuilder initial={initial} />
}