Mediquo documentation home

mq-schedule

Multi-step appointment scheduling. Walks the patient through choosing a professional, slot, profile and payment, emitting events the host reacts to.

<mq-schedule> is a self-contained scheduling wizard. It handles two top-level flows — schedule (new appointment) and reschedule (modify an existing one) — through a small declarative set of steps: choose professional → slot → complete profile → confirm → pay → done.

It is routing-agnostic: it never navigates on its own. It emits semantic events (appointment-created, back) and the host decides what to do — show its own confirmation screen, route elsewhere, or mount the standalone success screen. The component assumes an already-exchanged access token; it performs no token exchange.

Dependencies

<mq-schedule> does not wrap the generic providers — mount them yourself as ancestors:

  • <mq-theme-provider> — design tokens / theming.
  • <mq-query-client-provider> — the TanStack Query client the wizard's data fetching relies on.

Inside <mq-router> these are already provided by the host, so the auth attributes below are omitted there.

Installation

npm install @mediquo/web-components
import "@mediquo/web-components/mq-schedule";
import "@mediquo/web-components/mq-theme-provider";
import "@mediquo/web-components/mq-query-client-provider";

Usage

HTML

<mq-theme-provider theme="mediquo">
  <mq-query-client-provider>
    <mq-schedule
      env="production"
      api-key="<your-api-key>"
      token="<already-exchanged-access-token>"
      locale="es_ES"
      timezone="Europe/Madrid"
      default-specialty="ginecologia"
    ></mq-schedule>
  </mq-query-client-provider>
</mq-theme-provider>

React / Next.js

"use client";
import { useEffect, useRef } from "react";

export function Schedule({ apiKey, token }) {
  const ref = useRef<HTMLElement>(null);

  useEffect(() => {
    import("@mediquo/web-components/mq-schedule");
    import("@mediquo/web-components/mq-theme-provider");
    import("@mediquo/web-components/mq-query-client-provider");
  }, []);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;

    const onCreated = (e: Event) => {
      const { appointmentId } = (e as CustomEvent).detail;
      // route to confirmation / show success screen
    };
    const onBack = () => {
      // user left the wizard — route away / close
    };

    el.addEventListener("appointment-created", onCreated);
    el.addEventListener("back", onBack);
    return () => {
      el.removeEventListener("appointment-created", onCreated);
      el.removeEventListener("back", onBack);
    };
  }, []);

  return (
    /* @ts-expect-error — custom element */
    <mq-theme-provider theme="mediquo">
      {/* @ts-expect-error — custom element */}
      <mq-query-client-provider>
        {/* @ts-expect-error — custom element */}
        <mq-schedule
          ref={ref}
          env="production"
          api-key={apiKey}
          token={token}
          locale="es_ES"
          timezone="Europe/Madrid"
        />
      </mq-query-client-provider>
    </mq-theme-provider>
  );
}

Attributes & properties

NameTypeRequiredDescription
api-keystringStandaloneAPI key for the Mediquo platform. Omitted inside mq-router (the host configures the http client).
tokenstringStandaloneAlready-exchanged access token. No token exchange happens inside the component.
kind"schedule" | "reschedule"NoTop-level flow. Defaults to "schedule".
appointment-idstringWhen rescheduleAppointment to modify. Required when kind="reschedule".
default-specialtystringNoPre-selects a specialty. Accepts a public slug ("ginecologia") or a raw backend code.
default-servicestringNoPre-selects a service. Accepts a public slug ("videoconsulta") or a raw backend code.
default-professional-hashstringNoPre-selects a professional and starts the wizard at the slot picker.
requires-paymentbooleanNoIf false, the payment step is skipped. Defaults to true; always false for reschedule.
show-mediquo-brandingbooleanNoToggles the Mediquo logo in the layout header. Defaults to true.
localestringNoLocale code: es_ES, en_US, pt_PT, de_DE, ca_ES. Defaults to the host/build locale.
envstringNoBackend environment: "development" or "production". Applied once at mount.
timezonestringNoIANA timezone used to render slot times (e.g. "Europe/Madrid"). Not part of the patient profile, so the host supplies it; defaults to the browser's resolved timezone.

Events

All events bubble and cross shadow boundaries (composed: true).

EventDetailDescription
appointment-created{ appointmentId: string }The appointment was booked (or payment succeeded).
backThe user navigated back past the first step. The host decides where to go.
const schedule = document.querySelector("mq-schedule");

schedule.addEventListener("appointment-created", (e) => {
  // route to confirmation — e.detail.appointmentId
});
schedule.addEventListener("back", () => {
  // user left the wizard backwards — route away / close
});

Patient identity

The wizard needs minimal patient data (name for the header, timezone for slot times, hash for analytics). It reads name and hash from the patient profile API automatically; only timezone must be supplied by the host (via the attribute above), defaulting to the browser timezone. No login-token wiring is required.

The post-booking success screen (<mq-schedule-success>) is a separate element controlled by its own route — it is not part of this wizard.

Interactive playground

Documentation pages show usage only. For a full-page, interactive demo with sidebar → Devtools (dialog: API key, token, locale, theme, and an optional professional hash), open the standalone demo route on this site:

/web-components/mq-schedule/demo

The demo emits appointment-created and back as toasts so you can see the host-side callbacks fire.