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
headingstring–Section heading in the left column of the header
descriptionstring–Supporting paragraph, right-aligned from md up
triggerLabelstring–Small label on the inverted panel
triggerTitlestring–What starts the flow, set at display scale
triggerDetailstring–Supporting detail, right-aligned on the panel
branchesBranch[][]The paths the flow can take
closingstring–Paragraph beside the closing action
button{ label: string; href: string }–Outline closing action
classNamestring–Extra 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

PRO

workflow26

Process Flow

PRO

workflow54

Data Flow Map

Get Pro access