ContactChannelsPanel
Docyrus-backed contact points and consent for a record — preferred channels, per-kind channel cards, brand consent and a consent / validation history, with every endpoint wired through useDocyrusContactChannels.
Installation
pnpm dlx @docyrus/cli add @docyrus/rn-contact-channels-panelpnpm add @tanstack/react-query @docyrus/api-clientGive the panel an authenticated client and the owning (appSlug, dataSourceSlug, recordId). It loads the channels, the record-wide consent and validation ledgers and the tenant brands through useDocyrusContactChannels, and shows:
- a Summary of the preferred email and phone,
- channel sections (Emails and Phones always, other kinds when populated) with a card per channel (status, validated by, last validated, source, notes). The ⋯ button or a long-press opens the actions: Edit, Make primary, Record consent, Validate now, Archive / Restore and Delete permanently (with a confirm dialog),
- Brand consent cards (organization-wide, each tenant brand, and any other brand in a consent cache),
- a collapsible History of consent and validation events.
The editors (channel, consent, validation) are bottom sheets. Pull down to refresh. A Show archived switch adds archived channels, shown muted.
Renders inline by default (flex-1, or bounded with maxHeight). Pass onOpenChange to show it in an AwesomeDialog (a bottom sheet by default). Read endpoints need DS.Read.All, write endpoints DS.ReadWrite.All.
Usage
import { ContactChannelsPanel } from '@/components/docyrus-native/contact-channels-panel';
<ContactChannelsPanel client={client} appSlug="base" dataSourceSlug="contact" recordId={contactId} maxHeight={560} />
<ContactChannelsPanel
client={client}
appSlug="base"
dataSourceSlug="contact"
recordId={contactId}
subtitle="Erin Park · Acme"
open={open}
onOpenChange={setOpen} />Pair it with ContactChannelsField by opening the panel from the field's onDetailsClick.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
client | ContactChannelsClient | - | Authenticated REST client (RestApiClient fits) (required) |
appSlug | string | - | App slug of the owning record (required) |
dataSourceSlug | string | - | Data source slug of the owning record (required) |
recordId | string | - | Owning record id (required) |
title | string | 'Contact Points & Consent' | Heading (dialog mode) |
subtitle | string | - | Sub-heading (dialog mode) |
includeArchived | boolean | false | Start with archived channels shown |
enabled | boolean | - | Defer all queries |
loadBrands | boolean | true | Fetch /v1/tenant/brands |
readOnly | boolean | - | Hide every write affordance |
maxHeight | number | - | Max inline height in px (unbounded flex-1 when omitted) |
onChange | (channels: ContactChannel[]) => void | - | Fired with the refreshed channel list |
className | string | - | Container classes |
open | boolean | - | Dialog mode open state |
onOpenChange | (open: boolean) => void | - | Enables dialog mode |
container | 'modal' | 'sheet' | 'drawer' | 'sheet' | Dialog container |
side | 'left' | 'right' | 'top' | 'bottom' | 'bottom' | Sheet side |
size | 'sm' | 'default' | 'lg' | 'xl' | 'full' | 'xl' | Dialog size |
Components
| Component | Description |
|---|---|
ContactChannelsPanel | The panel |
ChannelCard | Channel read card with the actions sheet |
ChannelFormDialog | Add / edit channel sheet (draftToInput maps a draft to ChannelCreateInput) |
ConsentDialog | Record-consent sheet |
ValidationDialog | Record-validation sheet |
BrandConsentCard | Per-brand consent card |
ConsentHistory | Merged history |
PanelSummary | Preferred email / phone |
BrandMark, ChannelStatusIcon, ProviderBadge, StatusText, DialogField | Display helpers |
lib/panel-utils (synced with web): CHANNEL_SECTIONS, channelsOfKind, primaryOfKind, channelValidationDisplay, channelMetaString, brandMediumStatus, brandKeysInUse, resolveBrand, latestConsentForBrand, evidenceFromProof, latestValidationFor, fmtDay, fmtDateTime, ORG_BRAND_KEY.
Type Exports
| Type | Description |
|---|---|
ContactChannelsPanelProps | Props |
ChannelCardProps, ChannelCardActions, ChannelFormDialogProps, ConsentDialogProps, ValidationDialogProps, BrandConsentCardProps, ConsentHistoryProps | Sub-component props |
ChannelSectionMeta, ConsentDetail | Panel utils types |
ContactChannelsClient, UseDocyrusContactChannelsOptions, UseDocyrusContactChannelsResult, ContactChannelsPanelData, ConsentEntryWithChannel | Re-exported from the hook |
Differences from web
maxHeightis a number (px).sidedefaults to'bottom'(web:'right').- The refresh button is replaced by pull-to-refresh.