Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Blocks

CRM Pipeline Page

Blocks

CRM Pipeline Page React block for Tailwind CSS v4

CRM Contact PageError Pages
Live props
State
defaultPipeline
defaultView
defaultOpenDeal
loading
Behavior
currentUserId
largeDealAmount
staleAfterDays14d
requireLostReason
locale
currency
animateIn
Layout
height
showSummary
defaultShowClosed
Appearance
tone
radius
Code
import { CrmPipelinePage } from "@/components/blocks/crm-pipeline-page"

<CrmPipelinePage />
  1. Home
  2. Components
  3. Blocks
  4. CRM Pipeline Page
Pro

CRM Pipeline Page React block for Tailwind CSS v4

v1.0.1·Updated in 1.9.0

A React CRM pipeline page: pipeline switcher, search and filters, a deals board or list with totals, a deal sheet and a new deal dialog.

Switch the pipeline from the title (B2B sales or Partnerships; a bottom sheet on phones): the filters reset, the view stays. Pick a close date range in the header (This month, Next month, This quarter, Next 90 days, or two months of days; clear it with its ×). Type in the search to find a deal by title, company or contact, press Mine, No activity 14+ days or Over $10,000, and Clear filters to reset; the new count is announced. The board's own toolbar switches Board and List, filters by owner chips and hides or shows the won and lost columns; its summary follows the filters. Drag a card to another stage (long press on touch, or focus it and use Space and the arrows), or use its ⋯ menu (Move to, Mark as won, Mark as lost, Open, Delete). A drop on Lost asks for the reason first. Moves save optimistically; a failed save springs the card back with a toast. + Add deal under a column adds one by title. Click, tap or press Enter on a card to open its sheet (from the right, a tall bottom sheet on phones): rename it inline, change the value, stage, close date and owner, read the contact and the details, write a note (⌘ Enter adds it) and read the activity; Save appears once something changed, Mark as won and Lost close it (the reason dialog requires a reason), Reopen brings a closed deal back, ⋯ deletes it with an undo toast. Closing the sheet with unsaved changes asks Discard your changes? first; Escape closes it and focus returns to the card. New deal (or + on phones) opens a validated form: title, a company combobox that can add a new company, its contacts, value, stage, close date (30 days out by default) and owner; the new deal lands in its column. Sections rise in once on mount; reduced motion keeps everything still.

CRM Pipeline Page is a Pro React block in the React blocks category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add crm-pipeline-page, together with Alert, Alert Dialog, Avatar, Badge, Button and 31 more and the npm packages motion, lucide-react, react-hook-form and zod.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add crm-pipeline-page

CRM Pipeline Page is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import CrmPipelinePage from @/components/blocks/crm-pipeline-page.

// app/(admin)/deals/page.tsx (the shell lives in app/(admin)/layout.tsx: <AdminShell layout="fill">{children}</AdminShell>)
"use client"

import { CrmPipelinePage, type CrmDeal } from "@/components/blocks/crm-pipeline-page"

export default function OportunitatiPage() {
  return (
    <CrmPipelinePage
      height="fill"
      currentUserId="ana-pop"
      onDealMove={async (move) => {
        await fetch(`/api/deals/${move.deal.id}`, {
          method: "PATCH",
          body: JSON.stringify({ stageId: move.to.id, lostReason: move.lostReason }),
        })
      }}
      onDealCreate={async (deal: CrmDeal) => {
        const response = await fetch("/api/deals", { method: "POST", body: JSON.stringify(deal) })
        return (await response.json()) as CrmDeal
      }}
    />
  )
}

Props

  • pipelines
    CrmPipeline[]

    The pipelines ({ id, name, stages: DealStage[] }) of the title switcher; defaults to CRM_PIPELINE_SAMPLE.pipelines (B2B sales and Partnerships).

  • pipeline
    string

    The shown pipeline's id, controlled; pair it with onPipelineChange.

  • defaultPipelinedefault "b2b-sales"
    string

    The pipeline shown first while uncontrolled.

  • onPipelineChange
    (pipeline: string) => void

    Called when the title switcher picks another pipeline.

  • deals
    CrmDeal[]

    Every pipeline's deals, controlled (DealData plus companyId, contactId, createdAt, source, products and activity); a deal belongs to the pipeline that has its stage.

  • defaultDeals
    CrmDeal[]

    The deals while uncontrolled; defaults to CRM_PIPELINE_SAMPLE.deals (the 12 W8 deals and 4 partnerships).

  • onDealsChange
    (deals: CrmDeal[]) => void

    Called with the whole new list after every move, edit, create and delete.

  • view
    "board" | "list"

    The board or the grouped list, controlled.

  • defaultViewdefault "board"
    "board" | "list"

    The view while uncontrolled; switching pipelines keeps it.

  • onViewChange
    (view: DealPipelineView) => void

    Called when the board's Board / List switch changes.

  • owners
    { id: string; name: string; avatar?: string; role?: string }[]

    The sales team for the owner pickers; defaults to CRM_PIPELINE_SAMPLE.owners.

  • companies
    CrmPipelineCompany[]

    Clients and their contacts for the new deal form and the sheet's contact card; defaults to CRM_PIPELINE_SAMPLE.companies.

  • lostReasons
    string[]

    The reasons offered when a deal is lost; defaults to Price, Chose a competitor, Not enough budget, No decision, Other reason.

  • currentUserIddefault "ana-pop"
    string

    Who you are: the Mine chip and the default owner of new deals.

  • ownerFilter
    string[]

    The owner ids pressed in the board's owner chips (Mine presses yours), controlled.

  • defaultOwnerFilter
    string[]

    The owner filter while uncontrolled; defaults to [] (everyone).

  • onOwnerFilterChange
    (owners: string[]) => void

    Called when an owner chip or Mine changes the filter.

  • closePeriod
    DateRange | null

    The expected close date filter, controlled; null shows every date.

  • defaultClosePeriod
    DateRange | null

    The close date filter while uncontrolled; defaults to null.

  • onClosePeriodChange
    (period: DateRange | null) => void

    Called when the header's date range is picked or cleared.

  • largeDealAmountdefault 10000
    number

    The threshold of the Over $10,000 chip, in the page currency.

  • heightdefault "auto"
    "auto" | "fill" | "screen"

    fill takes what is left of a shell with layout="fill" and scrolls the board inside; screen is a standalone h-dvh page; auto grows with the longest column. Phones scroll the page around a tall board.

  • showSummarydefault true
    boolean

    The board's summary tiles (open pipeline, weighted forecast, won this month, win rate, average deal).

  • defaultShowCloseddefault true
    boolean

    Whether the Won and Lost columns start visible (the board's Show closed switch).

  • staleAfterDaysdefault 14
    number

    Days in a stage before a card shows the stale hint, and the No activity chip's threshold; 0 turns both off.

  • requireLostReasondefault true
    boolean

    A move to Pierdut (drag, menu, sheet) asks for a reason and blocks until one is chosen.

  • defaultOpenDealdefault ""
    string

    A deal id whose sheet opens on mount.

  • onDealMove
    (move: DealMove) => (boolean | void | Promise<unknown>)

    A drop, a menu move or a sheet move. false refuses it, a promise keeps the card saving and a rejection springs it back with a toast. Without it a 600 ms request is simulated.

  • onDealSave
    (deal: CrmDeal) => (void | Promise<unknown>)

    The sheet's saves (title, value, close date, owner, a note), optimistic; a rejection rolls back with a toast. Simulated by default.

  • onDealCreate
    (deal: CrmDeal) => (void | CrmDeal | Promise<void | CrmDeal>)

    A deal from the dialog or a column's quick add; resolve with the stored deal to replace the draft. A rejection shows the error in the dialog. Simulated by default.

  • onDealDelete
    (deal: CrmDeal) => (void | Promise<unknown>)

    Deleting from a card or the sheet, after a confirm; an undo toast follows, a rejection restores it. Simulated by default.

  • labels
    Partial<CrmPipelinePageLabels>

    Every visible string (English by default, DEFAULT_CRM_PIPELINE_PAGE_LABELS); CRM_PIPELINE_PAGE_LABELS_RO is the ready Romanian set. Nested keys (pipeline, dateRange, datePicker, datePresets, currencyInput, inlineEdit, select, contactCard, timeline, validation) translate the composed items.

  • localedefault "en-US"
    string

    Intl locale for money, numbers and dates.

  • currencydefault "USD"
    string

    The pipeline currency; deals in another currency are counted apart, never converted.

  • now
    Date | number

    The reference time for stale hints, overdue dates and new stamps; defaults to the live clock.

  • tonedefault "neutral"
    "neutral" | "brand" | "success" | "warning" | "danger" | "info"

    The accent of the primary actions, the pressed chips, the probability bars and the win rate ring.

  • radiusdefault "md"
    "sm" | "md" | "lg"

    The summary tiles, the empty state, the sheet and the dialogs (12px, 16px or 24px tiles).

  • loadingdefault false
    boolean

    The header, the summary and the columns as skeletons.

  • animateIndefault true
    boolean

    The header and the board rise in once on mount; off in thumbnails and under reduced motion.

  • linkComponentdefault "<a>"
    (props: LinkComponentProps) => ReactNode

    The router link for the company and deal links; defaults to the LinkProvider's (a plain anchor).

  • className
    string

    Merged onto the root.

  • classNames
    Partial<Record<CrmPipelinePageSlot, string>>

    Classes for the parts: header, filters, board, sheet, newDialog, empty.

Parts

  • DEFAULT_CRM_PIPELINE_PAGE_LABELS

    constant

    Every English string of the pipeline page: toolbar, board, list, deal sheet, new deal dialog and announcements. Spread it and override what you translate.

  • CRM_PIPELINE_PAGE_LABELS_EN

    constant

    An alias of DEFAULT_CRM_PIPELINE_PAGE_LABELS, kept so older imports keep working.

  • CRM_PIPELINE_PAGE_LABELS_RO

    constant

    A ready Romanian set of every string. Pass it as labels for a Romanian CRM.

  • CRM_PIPELINE_SAMPLE

    constant

    The demo content in one object: pipelines, deals, owners, companies, lost reasons, sources, now and the current user. Replace it with data from your API.

  • CRM_PIPELINES

    constant

    The sample pipelines with their stages and win probabilities, for the pipeline switcher.

  • CRM_PIPELINE_OWNERS

    constant

    The sample sales team that owns the deals, with names and avatars.

  • CRM_PIPELINE_COMPANIES

    constant

    The sample client companies the deals belong to, offered in the new deal dialog.

  • CRM_LOST_REASONS

    constant

    The reasons offered when a deal is marked lost: price, a competitor, budget, no decision and other.

  • CRM_DEAL_SOURCES

    constant

    The lead sources offered for a deal: referral, website, event, cold call, existing client and partner.

  • CRM_PIPELINE_NOW

    constant

    The fixed "now" of the sample (September 24, 2026, 4:40 PM) that close dates are measured from.

  • CRM_PIPELINE_DEAL_IDS

    constant

    The four sample deal ids the demo offers for defaultOpenDeal.

Examples

Open

Deal sheet open on ERP integration

defaultOpenDeal="d02": Construct Group, $103,400 in Negotiation, with its contact and activity.

Open

List view

defaultView="list": a table grouped by stage with totals; cards on phones.

Open

Only my deals

The Mine chip pressed, closed columns hidden: Needs analysis and Negotiation are empty.

Open

The Partnerships pipeline

defaultPipeline="partnerships": three stages, four deals, no lost column.

Open

Brand tone, large radius

tone="brand" on the primary actions, the chips and the probability bars; radius="lg".

Open

Loading

loading: the header, the summary and the columns as skeletons.

Open

Romanian copy, RON

CRM_PIPELINE_PAGE_LABELS_RO, locale="ro-RO", currency="RON": the ready Romanian set for the page and its parts.

Dependencies

motionlucide-reactreact-hook-formzodalertalert-dialogavatarbadgebuttoncomboboxcontact-cardcurrency-inputdate-pickerdate-range-pickerdeal-pipelinedescription-listdialogdropdown-menuempty-stateinline-editinputkbdpage-headersearch-inputselectsheettagtextareatimelinetoastuse-controllable-statecommercedate-utilsform-validationmotionnavigationnumber-formatrelative-timetonesui-config

Files

  • components/blocks/crm-pipeline-page.tsx
  • components/blocks/crm-pipeline-page-data.ts

FAQ

Is the React CRM Pipeline Page block free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install CRM Pipeline Page?

Run npx wingo-ui@latest add crm-pipeline-page. It also adds the Wingo UI items it builds on (Alert, Alert Dialog, Avatar, Badge, Button and 31 more) and the npm packages motion, lucide-react, react-hook-form and zod. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/crm-pipeline-page.

How does CRM Pipeline Page behave on phones?

Switch the pipeline from the title (B2B sales or Partnerships; a bottom sheet on phones): the filters reset, the view stays.

See also

Deal PipelineKanbanSheetAdmin ShellAdmin Dashboard Page

More React blocks

Error PagesInbox PageInvoice PageKPI DashboardListing Detail PageMarketplace Search Page
All 26 React blocks

Articles using this component

  • React CRM Template: Pipeline, Forecast, Company Pages

    Build it: screens and apps · Oct 16, 2026 · 11 min read

PreviousCRM Contact PageNext Error Pages