WingoUI
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime Picker
Forms
Address InputCSV 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 CardPopoverSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSkeletonSpinnerToast
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 chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage CropperImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Gravity Letters
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 PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowPost Listing WizardPricing PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAI Product PageBlog PageBlog Post PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePress PageProduct Tour PageReferral PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageTemplate Gallery PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Templates

ROI Calculator Page

Templates

ROI Calculator Page

Design
Roadmap PageSecurity Page
Design
Live props
Appearance
design
alternate
tone
ctaTone
radius
Behavior
maxTeam
readSharedInputs
animateIn
locale
currency
State
defaultHorizon
Layout
showAnnouncement
showTimeline
showReport
showWeek
showAssumptions
showCustomers
showFaq
showCta
showShare
showSummaryBar
ctaVariant
header
footer
Code
import { RoiCalculatorPage } from "@/components/templates/roi-calculator-page"

<RoiCalculatorPage />
  1. Home
  2. Templates
  3. ROI Calculator Page
Pro

ROI Calculator Page

v1.0.0·Added in 1.8.0

An interactive ROI page: team, hourly cost, lost hours and replaced tools in, yearly savings, payback, a breakdown and a savings chart out.

The page is the calculator. The hero rises in once, then the inputs panel asks for the team size (a slider plus a number field with steppers), the average hourly cost (a currency field with presets), the hours lost each week to status updates, searching and tool switching (three sliders), the tools Acme replaces (toggle chips with per-seat prices) and the plan and billing (segmented controls); Reset to defaults puts them back. The results panel, sticky beside the inputs on wide screens, rolls the yearly savings, ROI and hours back to their new values on motion values, shows the payback in days, a stacked breakdown bar with an Acme price marker and a tools-vs-Acme comparison. Get the full report scrolls to the report form; Share this estimate copies a link with the inputs in the query string, which the page reads back on load. Below, a cumulative value vs. cost chart (12, 24 or 36 months) marks the break-even day; hover, tap or drag across it for a crosshair readout, or focus it and use Left / Right / Home / End (Escape clears). The report form checks the work email and company, then shows a drawn PDF preview with Report sent to. A before / after week calendar redraws from the inputs, the assumptions card edits every reduction, adoption, ramp-up and price (Reset assumptions), and customer proof, the FAQ and the closing band follow. On phones and tablets a summary bar pins to the bottom while the inputs are on screen; Details opens the results in a bottom sheet. Reduced motion keeps numbers and panels still.

Built with

The sections this page is made of. In the full-screen preview, hold Alt to outline each one on the page.

  • Marketing Sectionmarketing-section
  • Marketing Headermarketing-header
  • Marketing Footermarketing-footer
  • FAQ Sectionfaq-section
  • CTA Sectioncta-section

Add to a project

npx wingo-ui@latest add roi-calculator-page

Pro item: the CLI needs a Pro account. See plans

Usage

// app/(marketing)/roi/page.tsx
"use client"

import Link from "next/link"
import { RoiCalculatorPage } from "@/components/templates/roi-calculator-page"

export default function RoiRoute() {
  return (
    <RoiCalculatorPage
      linkComponent={Link}
      ctaTone="brand"
      onRequestReport={async (inputs, results, contact) => {
        const response = await fetch("/api/roi-report", {
          method: "POST",
          body: JSON.stringify({ inputs, net: results.net, ...contact }),
        })
        if (!response.ok) throw new Error("Could not send the report")
      }}
    />
  )
}

Props

  • designdefault "classic"
    "classic" | "bold" | "minimal"

    The whole page's look. classic: a dotted glow behind a start-aligned hero and raised panels; bold: a pill header, a giant title on a gradient mesh, an inverted results panel, rounder panels, FAQ cards, an image band and a wordmark footer; minimal: a transparent header, a centered hero, no glow, outlined flat panels, no gray bands and a simple footer. faqProps and ctaProps still win.

  • inputs
    RoiInputs

    Controlled calculator values: { teamSize, hourlyCost, tools, statusHours, searchHours, switchHours, plan, billing }. Use with onInputsChange.

  • defaultInputsdefault "ROI_DEFAULT_INPUTS"
    Partial<RoiInputs>

    The values on load and after Reset to defaults: 40 people, $55 an hour, four tools, 2.5 / 3 / 2 hours, Business billed yearly.

  • onInputsChange
    (inputs: RoiInputs) => void

    Fires on every edit, including the values read from a share link.

  • assumptions
    RoiAssumptions

    Controlled assumptions; use with onAssumptionsChange.

  • defaultAssumptionsdefault "ROI_DEFAULT_ASSUMPTIONS"
    Partial<RoiAssumptions>

    Reductions (40 / 30 / 20%), adoption 80%, half of the hours counted as value, 46 weeks, a 3-month ramp, 2 setup hours and the plan prices.

  • onAssumptionsChange
    (assumptions: RoiAssumptions) => void

    Fires when the assumptions card is edited or reset.

  • toolsdefault "ROI_TOOLS"
    RoiTool[]

    The tools Acme replaces: { id, name, description, price (per seat per month), icon? }.

  • customersdefault "ROI_CUSTOMERS"
    RoiCustomer[]

    Proof cards: { company, icon?, industry, metric, metricLabel, quote, name, role, detail }.

  • faqdefault "ROI_FAQ"
    FaqItem[]

    { question, answer } pairs about the method.

  • labelsdefault "DEFAULT_ROI_CALCULATOR_PAGE_LABELS"
    Partial<RoiCalculatorPageLabels>

    Every visible string; the ones with numbers in them are functions.

  • hrefsdefault "DEFAULT_ROI_CALCULATOR_PAGE_HREFS"
    Partial<RoiCalculatorPageHrefs>

    { announcement, signUp, sales, privacy, customers }.

  • maxTeamdefault 500
    number

    The team size slider's end and the largest value a share link may set.

  • defaultHorizondefault "36"
    12 | 24 | 36

    The chart's time range on load, in months (a number; the playground passes it as text).

  • readSharedInputsdefault true
    boolean

    Reads team, rate, tools, status, search, switch, plan and billing from the query string after mount.

  • showAnnouncementdefault true
    boolean

    The strip above the header bar.

  • showTimelinedefault true
    boolean

    The savings over time chart (and the report form beside it).

  • showReportdefault true
    boolean

    The Get the full report form and the buttons that lead to it.

  • showWeekdefault true
    boolean

    The before / after week calendars.

  • showAssumptionsdefault true
    boolean

    The method, the editable assumptions and the survey footnote.

  • showCustomersdefault true
    boolean

    The customer proof cards.

  • showFaqdefault true
    boolean

    The FAQ.

  • showCtadefault true
    boolean

    The closing call to action.

  • showSharedefault true
    boolean

    The Share this estimate button.

  • showSummaryBardefault true
    boolean

    The bottom summary bar below 1024px and its results sheet.

  • ctaVariantdefault "inverted"
    "inverted" | "soft" | "split"

    The closing band: a solid band, a gray band, or copy beside the buttons on a raised panel. Applies to the classic design.

  • alternatedefault true
    boolean

    Gray bands on every other section. Applies to the classic and bold designs.

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

    Accents: the hero badge, the glow, sliders, segmented thumbs and selected tool chips.

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

    Get the full report, Email me the report, Details, the header's Get started and the closing band; brand is the marketing orange.

  • radiusdefault "md"
    "none" | "sm" | "md" | "lg" | "full"

    The corners of the form fields.

  • headerdefault true
    boolean

    The marketing header; off inside a site layout.

  • footerdefault true
    boolean

    The marketing footer with its newsletter form.

  • headerProps
    Partial<MarketingHeaderProps>

    Passed to MarketingHeader.

  • footerProps
    Partial<MarketingFooterProps>

    Passed to MarketingFooter.

  • faqProps
    Partial<FaqSectionProps>

    Overrides for the FaqSection.

  • ctaProps
    Partial<CtaSectionProps>

    Overrides for the CtaSection.

  • onRequestReport
    (inputs: RoiInputs, results: RoiResult, contact: { email, company }) => (void | Promise<unknown>)

    The report form. A promise keeps the button loading and a rejection shows an error. Without it the form waits 900 ms and shows the sent state with a drawn PDF preview.

  • onShare
    (url: string, inputs: RoiInputs) => void

    The share link was built and copied (or the copy failed).

  • onSubscribe
    (email: string) => (void | Promise<unknown>)

    The footer newsletter; a rejected promise shows an error.

  • animateIndefault true
    boolean

    The hero rises in once and numbers roll to new values; false keeps the page still (thumbnails). Reduced motion always does.

  • localedefault "en-US"
    string

    Intl locale for money, hours and percentages.

  • currencydefault "USD"
    string

    ISO currency of the hourly cost, tool prices and results (amounts are not converted).

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

    The router link for every link on the page (next/link in an app).

  • className
    string

    Classes for the root.

  • classNames
    Partial<Record<RoiCalculatorPageSlot, string>>

    Classes for header, hero, title, inputs, results, timeline, chart, report, week, assumptions, customers, customer, faq, cta, summary and footer.

Parts

  • computeRoi

    function

    The pure estimate: (inputs, assumptions = ROI_DEFAULT_ASSUMPTIONS, tools = ROI_TOOLS) => RoiResult with hours back, time value, tool savings, Acme cost, net yearly savings, ROI %, the multiple, payback days (day by day, with ramp-up, setup and billing days) and a 36-month cumulative timeline.

  • encodeRoiInputs

    function

    The share link's query values for some inputs: { team, rate, tools, status, search, switch, plan, billing }.

  • decodeRoiInputs

    function

    (params, tools?, maxTeam?) => the valid inputs found in a query string; unknown tools are dropped and numbers clamped.

  • ROI_SHARE_KEYS

    constant

    The query keys the share link uses.

  • ROI_CALCULATOR_SAMPLE

    constant

    All the sample content in one object: tools, inputs, assumptions, customers and faq.

  • ROI_DEFAULT_INPUTS

    constant

    The calculator's starting values.

  • ROI_DEFAULT_ASSUMPTIONS

    constant

    The survey-based assumptions and the plan prices (Pro $12 / $10, Business $24 / $20 per seat per month).

  • ROI_LIMITS

    constant

    { maxTeam: 500, maxHourly: 400, maxHours: 10 }.

  • ROI_TOOLS

    constant

    Seven generic tools with typical per-seat prices: task tracker, docs editor, team wiki, automation tool, status meetings app, roadmap tool and video updates.

  • ROI_CUSTOMERS

    constant

    Northwind, Umbrella Health and Stark Logistics proof cards.

  • ROI_FAQ

    constant

    Six questions about the defaults, the value share, hourly cost, payback, renewals and quotes.

  • DEFAULT_ROI_CALCULATOR_PAGE_LABELS

    constant

    The English strings.

  • DEFAULT_ROI_CALCULATOR_PAGE_HREFS

    constant

    The default link targets.

  • ROI_CALCULATOR_PAGE_DESIGNS

    constant

    The design names, classic first: ["classic", "bold", "minimal"].

  • RoiCalculatorPageProps

    type

    Props of RoiCalculatorPage.

  • RoiCalculatorPageDesign

    type

    "classic" | "bold" | "minimal".

  • RoiInputs

    type

    The calculator's values.

  • RoiAssumptions

    type

    The editable assumptions and prices.

  • RoiResult

    type

    What computeRoi returns.

  • RoiTool

    type

    One tool Acme replaces.

  • RoiCustomer

    type

    One proof card.

  • RoiReportContact

    type

    { email, company } from the report form.

  • RoiCalculatorPageLabels

    type

    The strings labels can override.

  • RoiCalculatorPageHrefs

    type

    The link targets hrefs can override.

Examples

Open

Bold design

design="bold": a giant title on a gradient mesh, an inverted results panel, rounder panels, FAQ cards and a wordmark footer.

Open

Minimal design

design="minimal": a transparent header, a centered hero, outlined flat panels, no gray bands and a simple footer.

Open

Small agency in brand orange

defaultInputs for 8 people on Pro, billed monthly, with tone and ctaTone brand and a 12-month chart.

Open

Euro pricing, embedded

locale de-DE and currency EUR without the header and footer, as the page would sit inside an existing site.

Open

Mailer down

An onRequestReport that rejects: fill in the report form and submit to see the error while the values stay in place.

Dependencies

lucide-reactmotiond3-shapemarketing-sectionmarketing-headermarketing-footerfaq-sectioncta-sectionavatarbuttoncurrency-inputdrawerfieldinputnumber-inputsegmented-controlsliderchart-kituse-controllable-statemotionnavigationtonesui-config

Files

  • components/templates/roi-calculator-page.tsx
  • components/templates/roi-calculator-page-data.ts

See also

Pricing PageStartups PageEnterprise PageArea chartSlider
PreviousRoadmap PageNext Security Page