Branching Decision Flow

What happens next

A cancellation takes one of two paths, and neither needs a phone call

This is the whole decision. There is no third branch and no manual step hiding inside either of them.

The trigger

A member cancels an appointment

From their own reminder link, at any hour. The slot is released the moment they confirm, not when reception next opens the diary.

If somebody is waiting

The slot is offered down the list

Everyone whose preferences match is offered it at once, in the order they joined. The first to confirm takes it and the rest are told immediately.

Filled without anyone acting

84% of cancellations

Median eleven minutes from cancellation to a new confirmed booking.

Nobody confirms in time

6% of cancellations

After two hours it falls through to the second branch rather than sitting in limbo.

If the list is empty

The hour goes back to the rota

Rather than leaving a hole, the slot is released as bookable capacity and the clinician is told their afternoon has changed.

Booked by a new member

7% of cancellations

Picked up through the public booking page, usually within a day.

Closed for the day

3% of cancellations

If it is inside two hours the room is released and the clinician gets the time back.

Reception sees all of it happening and can step in at any point. They just do not have to, which is the difference.

See the waiting list rules
About this block

Branching Decision FlowPRO

A workflow that states one trigger on an inverted full-width panel, then forks into two equally weighted condition branches whose outcomes sit in nested cards carrying the share of cases they account for.

Workflow49: Branching Decision Flow

A workflow that states one trigger on an inverted full-width panel, then forks into two equally weighted condition branches whose outcomes sit in nested cards carrying the share of cases they account for.

Upgrade to Pro

Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.

Upgrade Now

Installation

Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.

Radix flavor

bash
npx shadcn add "https://ui.beste.co/r/workflow49?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://ui.beste.co/r-base/workflow49?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/workflow49.tsx plus the badge23 and button21 components it uses for the eyebrow and the closing action.

Quick start

The installed file exports workflow49Demo alongside the block: the exact props behind the preview above. Spread it to get a working flow in one line.

tsx
import { Workflow49, workflow49Demo } from "@/components/beste/block/workflow49";

export default function FlowPage() {
  return <Workflow49 {...workflow49Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Workflow49 } from "@/components/beste/block/workflow49";

export default function FlowPage() {
  return (
    <Workflow49
      badge={{ label: "What happens next" }}
      heading="A cancellation takes one of two paths, and neither needs a phone call"
      description="This is the whole decision. There is no third branch."
      triggerLabel="The trigger"
      triggerTitle="A member cancels an appointment"
      triggerDetail="From their own reminder link, at any hour. The slot is released the moment they confirm."
      branches={[
        {
          condition: "If somebody is waiting",
          title: "The slot is offered down the list",
          description: "Everyone whose preferences match is offered it at once, in join order.",
          outcomes: [
            {
              title: "Filled without anyone acting",
              description: "Median eleven minutes from cancellation to a new confirmed booking.",
              share: "84% of cancellations",
            },
          ],
        },
        {
          condition: "If the list is empty",
          title: "The hour goes back to the rota",
          description: "The slot is released as bookable capacity and the clinician is told.",
          outcomes: [
            {
              title: "Booked by a new member",
              description: "Picked up through the public booking page, usually within a day.",
              share: "7% of cancellations",
            },
          ],
        },
      ]}
      closing="Reception sees all of it happening and can step in at any point."
      button={{ label: "See the waiting list rules", href: "/product/waiting-list" }}
    />
  );
}

Props

PropTypeDefaultDescription
badge{ label: string }Eyebrow above the hairline rule, rendered through Badge23
headingstringSection heading in the left column of the header
descriptionstringSupporting paragraph, right-aligned from md up
triggerLabelstringSmall label on the inverted panel
triggerTitlestringWhat starts the flow, set at display scale
triggerDetailstringSupporting detail, right-aligned on the panel
branchesBranch[][]The paths the flow can take
closingstringParagraph beside the closing action
button{ label: string; href: string }Outline closing action
classNamestringExtra classes for the outer section
ts
type ActionLink = {
  label: string;
  href: string;
};

type Outcome = {
  title: string;
  description: string;
  share: string;
};

type Branch = {
  condition: string;
  title: string;
  description: string;
  outcomes: Outcome[];
};

Behavior notes

  • The branches are deliberately equal. There is no featured or primary flag, and both render on the same bg-muted surface, because a decision tree that visually favours one path is arguing rather than describing.
  • Hierarchy comes from surface contrast instead of connectors: the trigger is an inverted bg-foreground panel and the branches are muted, with a mt-4 gap chaining them. There is no connector line.
  • The trigger panel uses fixed background text tokens, since its surface is fixed.
  • Outcome cards use auto-rows-fr inside their grid, so every nested card in a branch is the same height even when one description wraps to two lines and another does not.
  • The outcome stack carries mt-auto, so the cards align along the bottom of both branch cards regardless of how long each branch's own description is.
  • Inside an outcome, the share sits under the title on mobile and moves beside it from md up, with md:shrink-0 keeping it on one line so the title wraps instead.
  • share is free text, so it can carry a percentage, a count, or a phrase.

More Workflow blocks

View all Workflow
PRO

workflow48

Approval Chain Trail

An approval workflow drawn as a vertical rail of nodes tinted by whether each step is done, waiting, or queued, naming the person and the timestamp, beside a tile floating the live request card.

PRO

workflow26

Process Flow

Horizontal connected process steps with numbered nodes on a continuous rail.

PRO

workflow54

Data Flow Map

An integration map naming every system as a card, inverting the first-party one so it reads as the origin, then listing each crossing on a hairline row with what travels and how often.

PRO

workflow12

Workflow Canvas Hero

Hero with a full canvas on the right showing a real workflow flow: trigger node, condition node, and two action branches connected with lines.

PRO

workflow36

Process Timeline

A single-rail vertical process timeline with numbered nodes and per-step duration and owner meta.

PRO

workflow17

Workflow Analytics Dashboard

Full-width analytics card with four KPI tiles, a CSS bar chart of the last 30 days, and a top-workflows leaderboard with share bars.