Invite Check

Shows a meeting's start in every guest's own time zone and flags 3 AM slots, weekends, holidays, typo'd domains and duplicate guests before you send.

StopsInvite lands at 3 AM for guests

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/invite-check.json

The files land in your project. They're yours to edit.

Usage

invite-check-usage.tsx
import { InviteCheck, type ExistingInvite, type HolidayLookup, type InviteGuest } from "@/components/ui/invite-check"

<InviteCheck
  title="Q4 roadmap sync"
  start={start}
  guests={guests}
  videoLink={videoLink}
  timeZone="Asia/Kolkata"
  orgDomains={orgDomains}
  existing={existing}
  holidayFor={holidayFor}
  onReschedule={(at) => setStart(at.getTime())}
  onAddVideoLink={() => setVideoLink("meet.google.com/qrx-wpta-kme")}
  onFixGuest={(email, next) => setGuests((gs) => gs.map((g) => (g.email === email ? { ...g, email: next } : g)))}
  onRemoveGuest={(email) => setGuests((gs) => gs.filter((g) => g.email !== email))}
  onOpenExisting={() => undefined}
/>

What it catches

  • Start time outside a guest's working hours, at night or on their weekend
  • Guest's holiday, from your holiday source
  • Company domain typos among guests
  • No video link and no location
  • Duplicate guests hidden by +tags or Gmail dots, and an invite already sent

Props

InviteCheck props
PropTypeDefault
orgDomains

Your organisation's email domains. Guests elsewhere are marked external.

string[]—
existing

Invites already sent, to catch sending the same one twice.

ExistingInvite[]—
holidayForHolidayLookup—
title* (required)

Event title, used to spot a re-sent invite.

string—
start* (required)

Start of the event.

Date | number | string—
guests* (required)

People invited, each with an email and optional zone and hours.

InviteGuest[]—
location

Meeting place, if any.

string—
videoLink

Video call link, if any.

string—
timeZone

Your zone, for the suggested time. Defaults to the browser's.

string—
onReschedule

Move the event to the suggested start.

(start: Date) => void—
onAddVideoLink

Add a video link (Meet, Zoom, Teams…).

() => void—
onFixGuest

Replace a guest's address, e.g. a typo'd company domain.

(email: string, next: string) => void—
onRemoveGuest

Called with a guest's email to remove them.

(email: string) => void—
onOpenExisting

Open the invite this one duplicates.

(id: string) => void—
heading

Heading above the check.

string"Before you send"
noPlaceText

Shown when there is neither a location nor a video link.

string"No video link or location: guests won't know where to jo…
addVideoLabel

Button text to add a video link.

string"Add video link"
allClearText

Shown when nothing needs attention.

string"Works for everyone."

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Per-guest start times are a labelled list with text, not only icons
  • Issues and suggestions are in a polite live region
  • Every fix (reschedule, remove guest, add link) is a button

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Default working hours (9–18) and weekends are assumptions; pass each guest's real ones
  • Holidays come only from the source you provide
  • Needs each guest's IANA zone; it can't guess where they are

What it stops

Invite lands at 3 AM for guests

Also known as

calendar invite · meeting · time zone · guests · google meet · zoom link · scheduler · event

Dependencies

Pairs well with