Nasaq
Components

AnalyticsConnect

The connect-account empty state of an analytics page, built on IntegrationConnector, plus AnalyticsPageFrame, the shared page shell.

PreviewOpen ↗

Code

import { AnalyticsConnect, type IntegrationService } from "@fadymondy/nasaq/web";const service: IntegrationService = {  id: "ga",  name: "Google Analytics",  scopes: [{ id: "analytics.readonly", label: "See your Google Analytics reports", required: true }],  status: "disconnected",};export function Connect() {  return (    <AnalyticsConnect      service={service}      benefits={["Users and sessions against the previous period", "Sources and top pages"]}      onConnect={async () => { /* start OAuth */ }}      onDisconnect={async () => {}}    />  );}

Integrations · beta

Live examples and controls: AnalyticsConnect in the lab.

Install

npx shadcn@latest add https://docs.nasaqui.com/r/analytics-connect.json

An analytics page has nothing to show until an account is linked. AnalyticsConnect explains what connecting gives you (a short benefits list), then shows the one IntegrationConnector card for the service: a consent dialog listing the requested scopes, an account picker and a reconnect flow when the sign-in expired. AnalyticsPageFrame (exported from the same folder) is the shell all five analytics pages use: heading, period controls, refresh, disconnect and the connected line, and it switches to AnalyticsConnect when the service is not connected. No brand logo is drawn: the product name is text unless you pass its official logo as service.icon.

When to use

  • Before a Google Analytics, Search Console, YouTube or monitoring account is linked.
  • When a sign-in has expired (status: "needs-reauth").
  • As the shell of a report page via AnalyticsPageFrame.

When not to use

Import

import { AnalyticsConnect, AnalyticsPageFrame } from "@fadymondy/nasaq/web";

Quick start

import { AnalyticsConnect, type IntegrationService } from "@fadymondy/nasaq/web";

const service: IntegrationService = {
  id: "ga",
  name: "Google Analytics",
  scopes: [{ id: "analytics.readonly", label: "See your Google Analytics reports", required: true }],
  status: "disconnected",
};

export function Connect() {
  return (
    <AnalyticsConnect
      service={service}
      benefits={["Users and sessions against the previous period", "Sources and top pages"]}
      onConnect={async () => { /* start OAuth */ }}
      onDisconnect={async () => {}}
    />
  );
}

Anatomy

AnalyticsConnect       data-slot="analytics-connect"  data-status="disconnected|needs-reauth|…"
  heading + text
  benefits list
  IntegrationConnector (bare, one service)
AnalyticsPageFrame     data-slot="analytics-page"  data-connected
  header               title, description, actions, Refresh, Disconnect (confirm)
  connected line       status, account, updated time
  children | error | AnalyticsConnect

API

AnalyticsConnect

PropTypeDefaultDescription
serviceIntegrationServicerequiredThe service, its scopes and its state.
onConnect(id, scopeIds) => PromiserequiredStart OAuth for the ticked scopes.
onDisconnect(id) => PromiserequiredDisconnect.
onSelectAccount(id, accountId) => PromisenoneEnables the account picker.
benefitsreadonly string[]noneWhat the page will show.
title / descriptionReactNodenoneReplace the default heading and text.
connectorLabelsIntegrationConnectorProps["labels"]noneStrings of the inner connector.
classNamestringnoneExtra classes on the root.
labelsPartial<AnalyticsConnectLabels>noneReplace any built-in English or Arabic string.

AnalyticsPageFrame

PropTypeDefaultDescription
titleReactNoderequiredPage heading; the product name as text.
descriptionReactNodenoneSubtitle, such as the property.
serviceIntegrationServicerequiredConnected shows children; any other status shows AnalyticsConnect.
actionsReactNodenonePeriod toggle or other header controls.
error / onRetryReactNode / () => voidnoneReplace children with an error and retry.
onRefresh / refreshing / updatedAt() => Promise / boolean / datenoneRefresh button, its busy state and the updated time.
benefits, onConnect, onDisconnect, onSelectAccountnonenoneForwarded to AnalyticsConnect.
childrenReactNoderequiredThe report.
labelsPartial<AnalyticsPageFrameLabels>noneHeader strings.

Examples

Sign-in expired:

import { AnalyticsConnect } from "@fadymondy/nasaq/web";

export const Expired = () => (
  <AnalyticsConnect
    service={{ id: "gsc", name: "Search Console", scopes: [{ id: "webmasters.readonly", label: "See your Search Console data", required: true }], status: "needs-reauth", connectedAs: "[email protected]" }}
    onConnect={async () => {}}
    onDisconnect={async () => {}}
  />
);

As a page shell:

import { AnalyticsPageFrame, type IntegrationService } from "@fadymondy/nasaq/web";

export const Page = ({ service }: { service: IntegrationService }) => (
  <AnalyticsPageFrame title="Reports" service={service} onConnect={async () => {}} onDisconnect={async () => {}}>
    <p>The report goes here.</p>
  </AnalyticsPageFrame>
);

Accessibility

The empty state is a labelled section with a heading; the connector's dialog traps focus and lists each scope as a checkbox. Disconnect asks for confirmation in an alert dialog. Localise your benefits strings.

RTL & i18n

  • Text and lists align to the inline start; the connect button and dialog mirror.
  • The connected account (an email) is isolated left-to-right.
  • Logos are never mirrored.

Styling & tokens

  • Colours come from tokens (--primary, --nq-success, --nq-warning, --nq-danger, --nq-tag-*); never pass raw hex.
  • Uses the connector's tokens and a dashed --border frame.

Do / Don't

  • Do request only the read scopes the page needs.
  • Do show the product name as text unless you have its official logo.
  • Don't recolour or redraw a brand logo.

Lab

https://docs.nasaqui.com/?path=/docs/components-integrations-analytics-connect--docs

On this page