"use client"; /** * View-switcher for the flow editor. * * Renders a small Canvas / List pill above whichever view is active, * and conditionally mounts `` or ``. Why a * separate component: * - The page itself stays trivially small (loading + error + this). * - Either view can stay unaware of the other — they share data * (`{flow, nodes}`) and nothing else. * * View choice persists per-browser via localStorage so a power user * who prefers the list isn't fighting the default on every load. * Canvas is the default for everyone else — the original user * feedback was that the list shape made flows "hard to understand". */ import { useState } from "react"; import { LayoutGrid, ListTree } from "lucide-react"; import { FlowBuilder } from "./flow-builder"; import { FlowCanvas } from "./flow-canvas"; import { cn } from "@/lib/utils"; import type { FlowRow, FlowNodeRow } from "@/lib/flows/types"; type View = "canvas" | "list"; const STORAGE_KEY = "wacrm.flowEditor.view"; interface Props { initialFlow: FlowRow; initialNodes: FlowNodeRow[]; } export function FlowEditorShell({ initialFlow, initialNodes }: Props) { // Read the persisted choice in the useState initializer. Safe even // though this is a client component because the parent page only // mounts us AFTER a client-side fetch resolves — there's no SSR // pass for this subtree, so no hydration mismatch to worry about. // Default to `canvas` (the new default) when nothing is saved. const [view, setView] = useState(() => { try { const saved = window.localStorage.getItem(STORAGE_KEY); if (saved === "canvas" || saved === "list") return saved; } catch { // Private browsing / disabled storage — fall through to default. } return "canvas"; }); const choose = (next: View) => { setView(next); try { window.localStorage.setItem(STORAGE_KEY, next); } catch { // ignore } }; return (
choose("canvas")} icon={} label="Canvas" /> choose("list")} icon={} label="List" />
{view === "canvas" ? ( ) : ( )}
); } function ToggleButton({ active, onClick, icon, label, }: { active: boolean; onClick: () => void; icon: React.ReactNode; label: string; }) { return ( ); }